libwebp-0.4.0/0000755000014400001440000000000012255206714010053 5ustar libwebp-0.4.0/makefile.unix0000644000014400001440000002127512255002107012532 0ustar # This makefile is a simpler alternative to the autoconf-based build # system, for simple local building of the libraries and tools. # It will not install the libraries system-wide, but just create the 'cwebp' # and 'dwebp' tools in the examples/ directory, along with the static # libraries 'src/libwebp.a', 'src/libwebpdecoder.a', 'src/mux/libwebpmux.a' and # 'src/demux/libwebpdemux.a'. # # To build the library and examples, use: # make -f makefile.unix # from this top directory. #### Customizable part #### # These flags assume you have libpng, libjpeg, libtiff and libgif installed. If # not, either follow the install instructions below or just comment out the next # four lines. EXTRA_FLAGS= -DWEBP_HAVE_PNG -DWEBP_HAVE_JPEG -DWEBP_HAVE_TIFF DWEBP_LIBS= -lpng -lz CWEBP_LIBS= $(DWEBP_LIBS) -ljpeg -ltiff GIF_LIBS = -lgif ifeq ($(strip $(shell uname)), Darwin) # Work around a problem linking tables marked as common symbols, # cf., src/enc/yuv.[hc] # Failure observed with: gcc 4.2.1 and 4.0.1. EXTRA_FLAGS += -fno-common EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H EXTRA_FLAGS += -I/opt/local/include EXTRA_LIBS += -L/opt/local/lib GL_LIBS = -framework GLUT -framework OpenGL else GL_LIBS = -lglut -lGL endif # To install libraries on Mac OS X: # 1. Install MacPorts (http://www.macports.org/install.php) # 2. Run "sudo port install jpeg" # 3. Run "sudo port install libpng" # 4. Run "sudo port install tiff" # 5. Run "sudo port install giflib" # To install libraries on Linux: # 1. Run "sudo apt-get install libjpeg62-dev" # 2. Run "sudo apt-get install libpng12-dev" # 3. Run "sudo apt-get install libtiff4-dev" # 4. Run "sudo apt-get install libgif-dev" # Uncomment for build for 32bit platform # Alternatively, you can just use the command # 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect. # EXTRA_FLAGS += -m32 # Extra flags to enable experimental features and code # EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES # Extra flags to enable byte swap for 16 bit colorspaces. # EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP # Extra flags to enable multi-threading EXTRA_FLAGS += -DWEBP_USE_THREAD EXTRA_LIBS += -lpthread # Extra flags to emulate C89 strictness with the full ANSI EXTRA_FLAGS += -Wextra -Wold-style-definition EXTRA_FLAGS += -Wmissing-prototypes EXTRA_FLAGS += -Wmissing-declarations EXTRA_FLAGS += -Wdeclaration-after-statement EXTRA_FLAGS += -Wshadow # EXTRA_FLAGS += -Wvla #### Nothing should normally be changed below this line #### AR = ar ARFLAGS = r CC = gcc CPPFLAGS = -Isrc/ -Wall CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS) INSTALL = install GROFF = /usr/bin/groff COL = /usr/bin/col LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm DEC_OBJS = \ src/dec/alpha.o \ src/dec/buffer.o \ src/dec/frame.o \ src/dec/idec.o \ src/dec/io.o \ src/dec/layer.o \ src/dec/quant.o \ src/dec/tree.o \ src/dec/vp8.o \ src/dec/vp8l.o \ src/dec/webp.o \ DEMUX_OBJS = \ src/demux/demux.o \ DSP_DEC_OBJS = \ src/dsp/cpu.o \ src/dsp/dec.o \ src/dsp/dec_neon.o \ src/dsp/dec_sse2.o \ src/dsp/lossless.o \ src/dsp/upsampling.o \ src/dsp/upsampling_neon.o \ src/dsp/upsampling_sse2.o \ src/dsp/yuv.o \ DSP_ENC_OBJS = \ src/dsp/enc.o \ src/dsp/enc_neon.o \ src/dsp/enc_sse2.o \ ENC_OBJS = \ src/enc/alpha.o \ src/enc/analysis.o \ src/enc/backward_references.o \ src/enc/config.o \ src/enc/cost.o \ src/enc/filter.o \ src/enc/frame.o \ src/enc/histogram.o \ src/enc/iterator.o \ src/enc/layer.o \ src/enc/picture.o \ src/enc/quant.o \ src/enc/syntax.o \ src/enc/token.o \ src/enc/tree.o \ src/enc/vp8l.o \ src/enc/webpenc.o \ EX_FORMAT_DEC_OBJS = \ examples/jpegdec.o \ examples/metadata.o \ examples/pngdec.o \ examples/tiffdec.o \ EX_UTIL_OBJS = \ examples/example_util.o \ GIF2WEBP_UTIL_OBJS = \ examples/gif2webp_util.o \ MUX_OBJS = \ src/mux/muxedit.o \ src/mux/muxinternal.o \ src/mux/muxread.o \ UTILS_DEC_OBJS = \ src/utils/alpha_processing.o \ src/utils/bit_reader.o \ src/utils/color_cache.o \ src/utils/filters.o \ src/utils/huffman.o \ src/utils/quant_levels_dec.o \ src/utils/random.o \ src/utils/rescaler.o \ src/utils/thread.o \ src/utils/utils.o \ UTILS_ENC_OBJS = \ src/utils/bit_writer.o \ src/utils/huffman_encode.o \ src/utils/quant_levels.o \ LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS) LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \ $(UTILS_ENC_OBJS) LIBWEBPMUX_OBJS = $(MUX_OBJS) LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) HDRS_INSTALLED = \ src/webp/decode.h \ src/webp/demux.h \ src/webp/encode.h \ src/webp/mux.h \ src/webp/mux_types.h \ src/webp/types.h \ HDRS = \ src/dec/alphai.h \ src/dec/decode_vp8.h \ src/dec/vp8i.h \ src/dec/vp8li.h \ src/dec/webpi.h \ src/dsp/dsp.h \ src/dsp/lossless.h \ src/dsp/yuv.h \ src/enc/cost.h \ src/enc/vp8enci.h \ src/utils/alpha_processing.h \ src/utils/bit_reader.h \ src/utils/bit_writer.h \ src/utils/color_cache.h \ src/utils/filters.h \ src/utils/huffman.h \ src/utils/huffman_encode.h \ src/utils/quant_levels.h \ src/utils/quant_levels_dec.h \ src/utils/random.h \ src/utils/rescaler.h \ src/utils/thread.h \ src/webp/format_constants.h \ $(HDRS_INSTALLED) \ OUT_LIBS = examples/libexample_util.a src/libwebpdecoder.a src/libwebp.a OUT_EXAMPLES = examples/cwebp examples/dwebp EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES) ifeq ($(MAKECMDGOALS),clean) OUTPUT += $(EXTRA_EXAMPLES) OUTPUT += src/demux/libwebpdemux.a src/mux/libwebpmux.a OUTPUT += examples/libgif2webp_util.a endif ex: $(OUT_EXAMPLES) all: ex $(EXTRA_EXAMPLES) $(EX_FORMAT_DEC_OBJS): %.o: %.h %.o: %.c $(HDRS) $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ examples/libexample_util.a: $(EX_UTIL_OBJS) examples/libgif2webp_util.a: $(GIF2WEBP_UTIL_OBJS) src/libwebpdecoder.a: $(LIBWEBPDECODER_OBJS) src/libwebp.a: $(LIBWEBP_OBJS) src/mux/libwebpmux.a: $(LIBWEBPMUX_OBJS) src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS) %.a: $(AR) $(ARFLAGS) $@ $^ examples/cwebp: examples/cwebp.o $(EX_FORMAT_DEC_OBJS) examples/dwebp: examples/dwebp.o examples/gif2webp: examples/gif2webp.o examples/vwebp: examples/vwebp.o examples/webpmux: examples/webpmux.o examples/cwebp: src/libwebp.a examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS) examples/dwebp: examples/libexample_util.a src/libwebpdecoder.a examples/dwebp: EXTRA_LIBS += $(DWEBP_LIBS) examples/gif2webp: examples/libexample_util.a examples/libgif2webp_util.a examples/gif2webp: src/mux/libwebpmux.a src/libwebp.a examples/gif2webp: EXTRA_LIBS += $(GIF_LIBS) examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a examples/vwebp: src/libwebp.a examples/vwebp: EXTRA_LIBS += $(GL_LIBS) examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL examples/webpmux: examples/libexample_util.a src/mux/libwebpmux.a examples/webpmux: src/libwebpdecoder.a $(OUT_EXAMPLES) $(EXTRA_EXAMPLES): $(CC) -o $@ $^ $(LDFLAGS) dist: DESTDIR := dist dist: OUT_EXAMPLES += $(EXTRA_EXAMPLES) dist: all $(INSTALL) -m755 -d $(DESTDIR)/include/webp \ $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib $(INSTALL) -m755 -s $(OUT_EXAMPLES) $(DESTDIR)/bin $(INSTALL) -m644 $(HDRS_INSTALLED) $(DESTDIR)/include/webp $(INSTALL) -m644 src/libwebp.a $(DESTDIR)/lib $(INSTALL) -m644 src/demux/libwebpdemux.a $(DESTDIR)/lib $(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib umask 022; \ for m in man/[cd]webp.1 man/gif2webp.1 man/webpmux.1; do \ basenam=$$(basename $$m .1); \ $(GROFF) -t -e -man -T utf8 $$m \ | $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \ $(GROFF) -t -e -man -T html $$m \ | $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \ done clean: $(RM) $(OUTPUT) *~ \ examples/*.o examples/*~ \ src/dec/*.o src/dec/*~ \ src/demux/*.o src/demux/*~ \ src/dsp/*.o src/dsp/*~ \ src/enc/*.o src/enc/*~ \ src/mux/*.o src/mux/*~ \ src/utils/*.o src/utils/*~ \ src/webp/*~ man/*~ doc/*~ swig/*~ \ superclean: clean $(RM) -r .git *.log *.cache *~ $(RM) -r .deps */.deps */*/.deps $(RM) -r .libs */.libs */*/.libs $(RM) */*.lo */*/*.lo $(RM) */*.la */*/*.la $(RM) Makefile */Makefile */*/Makefile $(RM) Makefile.in */Makefile.in */*/Makefile.in $(RM) config.log autom4te.cache libtool config.h stamp-h1 $(RM) aclocal.m4 compile $(RM) config.guess config.h.in config.sub config.status $(RM) configure depcomp install-sh ltmain.sh missing src/libwebp.pc $(RM) m4/* .PHONY: all clean dist ex superclean .SUFFIXES: libwebp-0.4.0/Makefile.in0000644000014400001440000005751712255206714012137 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog NEWS ar-lib \ compile config.guess config.sub depcomp install-sh ltmain.sh \ missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src examples man EXTRA_DIST = COPYING autogen.sh all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @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 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive 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-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-generic distclean-hdr \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck 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-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am # 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: libwebp-0.4.0/ChangeLog0000644000014400001440000025454512255002107011632 0ustar 256e433 update NEWS description with new general features 2962534 Merge "gif2webp: don't use C99 %zu" into 0.4.0 3b9f9dd gif2webp: don't use C99 %zu b5b2e3c cwebp: fix metadata output w/lossy+alpha ad26df1 makefile.unix: clean up libgif2webp_util.a c3b4557 update Changelog ca84112 Merge "bump version to 0.4.0" into 0.4.0 8c524db bump version to 0.4.0 eec2398 update AUTHORS & .mailmap b9bbf6a update NEWS for 0.4.0 c72e081 Merge "dec/webp.c: don't wait for data before reporting w/h" 5ad6531 dec/frame.c: fix formatting f7fc4bc dec/webp.c: don't wait for data before reporting w/h 66a32af Merge "NEON speed up" 26d842e NEON speed up f307f98 Merge "webpmux: let -- stop parameter parsing" fe051da Merge "README: add a section on gif2webp" 6fd2bd6 Merge "manpage pedantry" 4af1900 README: add a section on gif2webp 6f36ade manpage pedantry f9016cb README: update dwebp options b4fa0a4 webpmux: let -- stop parameter parsing a9a20ac gif2webp: Add a multi-threaded encode option 495bef4 fix bug in TrellisQuantize 605a712 simplify __cplusplus ifdef 33109f9 Merge "drop: ifdef __cplusplus checks from C files" 7f9de0b Merge changes I994a5587,I8467bb71,I13b50688,I1e2c9c7b 5459030 gif2webp: let -- stop parameter parsing a4b0aa0 vwebp: let -- stop parameter parsing 98af68f cwebp: let -- stop parameter parsing a33831e dwebp: let -- stop parameter parsing 3630124 add some checks on error paths ce4c713 Merge "autoconf: add --disable-wic" 5227d99 drop: ifdef __cplusplus checks from C files f645355 dwebp.1: fix typo f91034f Merge "cwebp: print metadata stats when no output file is given" d493455 gif2webp: Backward compatibility for giflib version <= 4.1.3 4c617d3 gif2webp: Disable output of ICC profile by default 73b731f introduce a special quantization function for WHT 41c0cc4 Make Forward WHT transform use 32bit fixed-point calculation a3359f5 Only compute quantization params once 7049043 cwebp: print metadata stats when no output file is given d513bb6 * fix off-by-one zthresh calculation * remove the sharpening for non luma-AC coeffs * adjust the bias a little bit to compensate for this ad9dec0 Merge "cosmetics: dwebp: fix local function name format" f737f03 Merge "dwebp: remove a dead store" 3c3a70d Merge "makefile.unix: install binaries in $(DESTDIR)/bin/" 150b655 Merge "Android.mk: add some release compile flags" dbebd33 cosmetics: dwebp: fix local function name format 2774995 dwebp: remove a dead store a01e04f autoconf: add --disable-wic 5009b22 makefile.unix: install binaries in $(DESTDIR)/bin/ bab30fc Merge "fix -print_psnr / ssim options" ebef7fb fix -print_psnr / ssim options cb63785 Merge "fix bug due to overzealous check in WebPPictureYUVAToARGB()" 8189885 Merge "EstimateBestFilter: use an int to iterate WEBP_FILTER_TYPE" 4ad7d33 Android.mk: add some release compile flags c12e236 cosmetics: fix a few typos 6f10403 fix bug due to overzealous check in WebPPictureYUVAToARGB() 3f6c35c EstimateBestFilter: use an int to iterate WEBP_FILTER_TYPE cc55790 Merge changes I8bb7a4dc,I2c180051,I021a014f,I8a224a62 c536afb Merge "cosmetics: fix some typos" cbdd3e6 add a -dither dithering option to the decoder e812401 Updated iosbuild.sh for XCode 5.x 4931c32 cosmetics: fix some typos 05aacf7 mux: add some missing casts 617d934 enc/vp8l: add a missing cast 46db286 idec: add some missing casts b524e33 ErrorStatusLossless: correct return type cb261f7 fix a descaling bug for vertical/horizontal U/V interpolation bcb3955 Merge changes I48968468,I181bc736 73f5213 gif2webp: Add a mixed compression mode 6198715 demux: split chunk parsing from ParseVP8X d2e3f4e demux: add a tail pointer for chunks 87cffcc demux: cosmetics: s/has_frames/is_animation/ e18e667 demux: strictly enforce the animation flag c4f39f4 demux: cosmetics: remove a useless break 61cb884 demux: (non-exp) fail if the fragmented flag is set ff379db few % speedup of lossless encoding df3649a remove all disabled code related to P-frames 6d0cb3d Merge "gif2webp: kmin = 0 should suppress key-frame addition." 3655598 gif2webp: kmin = 0 should suppress key-frame addition. 7708e60 Merge "detect flatness in blocks and favor DC prediction" 06b1503 Merge "add comment about the kLevelsFromDelta[][] LUT generation" 5935259 add comment about the kLevelsFromDelta[][] LUT generation e3312ea detect flatness in blocks and favor DC prediction ebc9b1e Merge "VPLBitReader bugfix: Catch error if bit_pos > LBITS too." 96ad0e0 VPLBitReader bugfix: Catch error if bit_pos > LBITS too. a014e9c tune quantization biases toward higher precision 1e89861 add helpful PrintBlockInfo() function 596a6d7 make use of 'extern' consistent in function declarations c8d48c6 Merge "extract random utils to their own file util/random.[ch]" 98aa33c extract random utils to their own file util/random.[ch] 432a723 Merge "swig: add basic go bindings" fab618b Merge "rename libwebp.i -> libwebp.swig" e4e7fcd swig: add basic go bindings d340872 Merge "fast auto-determined filtering strength" f8bfd5c fast auto-determined filtering strength ac0bf95 small clean-up in ExpandMatrix() 1939607 rename libwebp.i -> libwebp.swig 43148b6 filtering: precompute ilimit and hev_threshold 18f992e simplify f_inner calculation a little 241d11f add missing const 86c0031 add a 'format' field to WebPBitstreamFeatures dde91fd Demux: Correct the extended format validation 5d6c5bd add entry for '-resize' option in cwebp's man 7c098d1 Use some gamma-curve range compression when computing U/V average 0b2b050 Use deterministic random-dithering during RGB->YUV conversion 8a2fa09 Add a second multi-thread method 7d6f2da Merge "up to 20% faster multi-threaded decoding" 266f63e Merge "libwebp.jar: build w/Java 1.6 for Android compat" 0532149 up to 20% faster multi-threaded decoding 38efdc2 Simplify the gif2webp tool: move the optimization details to util de89951 libwebp.jar: build w/Java 1.6 for Android compat cb22155 Decode a full row of bitstream before reconstructing dca8a4d Merge "NEON/simple loopfilter: avoid q4-q7 registers" 9e84d90 Merge "NEON/TransformWHT: avoid q4-q7 registers" fc10249 NEON/simple loopfilter: avoid q4-q7 registers 2f09d63 NEON/TransformWHT: avoid q4-q7 registers 77585a2 Merge "use a macrofunc for setting NzCoeffs bits" d155507 Merge "use HINT_GRAPH as image_hint for gif source" 9c56164 Merge "only print GIF_DISPOSE_WARNING once" 0587986 use HINT_GRAPH as image_hint for gif source 0b28d7a use a macrofunc for setting NzCoeffs bits f9bbc2a Special-case sparse transform 0012519 gif2webp: detect and flatten uniformly similar blocks 0deaf0f only print GIF_DISPOSE_WARNING once 6a8c0eb Merge "small optimization in segment-smoothing loop" f7146bc small optimization in segment-smoothing loop 5a7533c small gif2webp fix 4df0c89 Merge changes Ic697660c,I27285521 5b2e6bd Android.mk: add a dwebp target f910a84 Android.mk: update build flags 63f9aba special-case WHT transform when there's only DC 80911ae Merge "7-8% faster decoding by rewriting GetCoeffs()" 606c430 gif2webp: Improved compression for lossy animated WebP fb887f7 gif2webp: Different kmin/kmax defaults for lossy and lossless 2a98136 7-8% faster decoding by rewriting GetCoeffs() 92d47e4 improve VP8L signature detection by checking the version bits too 5cd43e4 Add -incremental option to dwebp 54b8e3f webpmux: DisplayInfo(): remove unnecessary error checks. 40ae352 fix memleak in WebPIDelete() d966265 mux.h doc: WebPMuxGetFrame() can return WEBP_MUX_MEMORY_ERROR too. 0e6747f webpmux -info: display dimensions and has_alpha per frame d78a82c Sanity check for underflow 8498f4b Merge "remove -Wshadow warnings" e89c6fc Avoid a potential memleak 3ebe175 Merge "break down the proba 4D-array into some handy structs" 6a44550 break down the proba 4D-array into some handy structs 2f5e893 remove -Wshadow warnings bf3a29b Merge "add proper WEBP_HAVE_GIF and WEBP_HAVE_GL flags" 2b0a759 Merge "fix some warnings from static analysis" 22dd07c mux.h: Some doc corrections 79ff034 add proper WEBP_HAVE_GIF and WEBP_HAVE_GL flags d51f45f fix some warnings from static analysis d134307 fix conversion warning on MSVC d538cea gif2webp: Support a 'min' and 'max' key frame interval 80b54e1 allow search with token buffer loop and fix PARTITION0 problem b7d4e04 add VP8EstimateTokenSize() 10fddf5 enc/quant.c: silence a warning 399cd45 Merge "fix compile error on ARM/gcc" 9f24519 encoder: misc rate-related fixes c663bb2 Merge "simplify VP8IteratorSaveBoundary() arg passing" fa46b31 Demux.h: Correct a method name reference f8398c9 fix compile error on ARM/gcc f691f0e simplify VP8IteratorSaveBoundary() arg passing 42542be up to 6% faster encoding with clang compiler 93402f0 multi-threaded segment analysis 7e2d659 Merge "remove the PACK() bit-packing tricks" c13fecf remove the PACK() bit-packing tricks 2fd091c Merge "use NULL for lf_stats_ testing, not bool" b11c9d6 dwebp: use default dct_method 4bb8465 Merge "(de)mux.h: wrap pseudo-code in /* */" cfb56b1 make -pass option work with token buffers 5416aab (de)mux.h: wrap pseudo-code in /* */ 35dba33 use NULL for lf_stats_ testing, not bool 733a7fa enc->Iterator memory cleanup e81fac8 Add support for "no blend" in webpmux binary 3b80bc4 gif2webp: Separate out each step into a method bef7e9c Add doc precision about demux object keeping pointers to data. 61405a1 dwebp: enable stdout output with WIC 6eabb88 Merge "Animated WebP: add "do no blend" option to spec" be20dec fix compilation for BITS 24 e58cc13 Merge "dwebp: s/unsigned char/uint8_t/" 72501d4 dwebp: s/unsigned char/uint8_t/ 2c9633e Merge "gif2webp: Insert independent frames at regular intervals." f0d6a14 gif2webp: Insert independent frames at regular intervals. b25a6fb yuv.h: fix indent ede3602 Merge "cosmetics: fix indent" 3a65122 dwebp: fix stdout related output 388a724 cosmetics: fix indent 4c7322c Merge "dsp: msvc compatibility" d50c7e3 Merge "5-7% faster SSE2 versions of YUV->RGB conversion functions" b8ab784 Merge "simplify upsampler calls: only allow 'bottom' to be NULL" df6cebf 5-7% faster SSE2 versions of YUV->RGB conversion functions ad6ac32 simplify upsampler calls: only allow 'bottom' to be NULL a5e8afa output to stdout if file name is "-" f358450 dsp: msvc compatibility 43a7c8e Merge "cosmetics" 4c5f19c Merge "bit_reader.h: cosmetics" f72fab7 cosmetics 14dd5e7 fix const-ness b20aec4 Merge "Support for 'do not blend' option in vwebp" dcf6522 Support for 'do not blend' option in vwebp d5bad03 Animated WebP: add "do no blend" option to spec a2f5f73 Merge "Support for "Do not blend" in mux and demux libraries" e081f2f Pack code & extra_bits to Struct (VP8LPrefixCode). 6284854 Support for "Do not blend" in mux and demux libraries f486aaa Merge "slightly faster ParseIntraMode" d171863 slightly faster ParseIntraMode 3ceca8a bit_reader.h: cosmetics 69257f7 Create LUT for PrefixEncode. 988b708 add WebPWorkerExecute() for convenient bypass 06e2498 Merge "VP8EncIterator clean-up" de4d4ad VP8EncIterator clean-up 7bbe952 Merge "cosmetics: thread.c: drop a redundant comment" da41148 cosmetics: thread.c: drop a redundant comment feb4b6e thread.h: #ifdef when checking WEBP_USE_THREAD 8924a3a thread.c: drop WebPWorker prefix from static funcs 1aed8f2 Merge "fix indent" 4038ed1 fix indent 1693fd9 Demux: A new state WEBP_DEMUX_PARSE_ERROR 8dcae8b fix rescaling-with-alpha inaccuracy 11249ab Merge changes I9b4dc36c,I4e0eef4d 52508a1 Mux: support parsing unknown chunks within a frame/fragment. 05db057 WebPMuxSetChunk: remove unused variable 8ba1bf6 Stricter check for presence of alpha when writing lossless images a03c351 Demux: WebPIterator now also denotes if the frame has alpha. 6df743a Decoder: handle fragments case correctly too. faa4b07 Support for unknown chunks in mux library 7d60bbc Speed up HashChainFindCopy function. 6674014 Speedup Alpha plane encoding. b7346a1 0.1 % speedup to decoding c606182 webp-container-spec: Tighten language added by last a34a502 pngdec: output error messages from libpng e84c625 Merge "Detect canvas and image size mismatch in decoder." f626fe2 Detect canvas and image size mismatch in decoder. f5fbdee demux: stricter image bounds check 30c8158 add extra assert in Huffman decode code 8967b9f SSE2 for lossless decoding (critical) functions. 699d80e Jump-lookup for Huffman coding c34307a fix some VS9 warnings about type conversion eeada35 pngdec: add missing include 54b6510 gif2webp: If aligning to even offsets, extra pixels should be transparent 0bcf5ce Merge "remove a malloc() in case we're using only FILTER_NONE for alpha" 2c07143 remove a malloc() in case we're using only FILTER_NONE for alpha a4d5f59 Faster lossless decoding fd53bb7 Merge "alternate LUT-base reverse-bits code" d1c166e Merge "Container spec: a clarification on background color." fdb9177 Rename a method 5e96753 Container spec: a clarification on background color. 30e77d0 Merge branch '0.3.0' 1b631e2 alternate LUT-base reverse-bits code 24cc307 ~20% faster lossless decoding 313d853 Speedup for decoding lossless WebP photographs: 24ee098 change the bytes_per_pixels_ field into more evocative use_8b_decode 2a04b03 update ChangeLog (tag: v0.3.1-rc2, tag: v0.3.1) 7288950 Regression fix for alpha channels using color cache: 2e377b5 wicdec: silence a format warning ad9e42a muxedit: silence some uninitialized warnings 3307c16 Don't set alpha-channel to 0xff for alpha->green uplift 5130770 Merge "wicdec: silence a format warning" a37eff4 Regression fix for alpha channels using color cache: 241cf99 Merge "muxedit: silence some uninitialized warnings" c8f9c84 Regression fix for alpha unfiltering: 14cd5c6 muxedit: silence some uninitialized warnings a368db8 dec/vp8l: quiet vs9 x64 type conversion warning ffae9f3 wicdec: silence a format warning 8cf0701 Alpha encoding: never filter in case of NO_COMPRESSION 825e73b update ChangeLog (tag: v0.3.1-rc1) abf6f69 update NEWS 5a92c1a bump version to 0.3.1 86daf77 store top Y/U/V samples in packed fashion 67bc353 Revert "add WebPBlendAlpha() function to blend colors against background" 068db59 Intertwined decoding of alpha and RGB 38cc011 Simplify forward-WHT + SSE2 version 3fa595a Support decoding upto given row in DECODE_DATA_FUNC 520f005 DequantizeLevels(): Add 'row' and 'num_rows' args 47374b8 Alpha unfilter for given set of rows f32097e probe input file and quick-check for WebP format. a2aed1d configure: improve gl/glut library test c7e89cb update copyright text a00380d configure: remove use of AS_VAR_APPEND a94a88d fix EXIF parsing in PNG a71e5d8 add doc precision for WebPPictureCopy() and WebPPictureView() 8287012 remove datatype qualifier for vmnv e190843 fix a memory leak in gif2webp 0b18b9e fix two minor memory leaks in webpmux db5095d remove some cruft from swig/libwebp.jar 850e956 README: update swig notes bddd9b0 swig/python: add minimal documentation d573a8d swig: add python encode support 6b93187 swig/java: reduce wrapper function code duplication 6fe536f swig/java: rework uint8_t typemap a2ea464 Fix the bug in ApplyPalette. 7bb28d2 webp/lossless: fix big endian BGRA output f036d4b Speed up ApplyPalette for ARGB pixels. 8112c8c remove some warnings: cc128e0 Further reduce memory to decode lossy+alpha images 07db70d fix for big-endian eda8a7d gif2webp: Fix signed/unsigned comparison mismatch 31f346f Makefile.vc: fix libwebpdemux dll variable typo 6c76d28 swig: add python (decode) support b4f5bb6 swig: cosmetics 498d4dd WebP-Lossless encoding improvements. 26e7244 swig: ifdef some Java specific code 8ecec68 configure: add warning related flags e676b04 configure: add GLUT detection; build vwebp b0ffc43 Alpha decoding: significantly reduce memory usage 20aa7a8 configure: add --enable-everything b8307cc configure.ac: add some helper macros 980e7ae Remove the gcc compilation comments 7f25ff9 gif2webp: Fix ICC and XMP support d8e5321 Add missing name to AUTHORS 11edf5e Demux: Fix a potential memleak c7b9218 don't forward declare enums 7a650c6 prevent signed int overflow in left shift ops 31bea32 add precision about dynamic output reallocation with IDecoder c22877f Add incremental support for extended format files 5051245 Makefile.vc: have 'all' target build everything 8191dec Makefile.vc: flags cleanup b9d7473 Makefile.vc: drop /FD flag 5568dbc update gitignore f4c7b65 WebPEncode: An additional check. Start VP8EncLoop/VP8EncTokenLoop only if VP8EncStartAlpha succeeded. 1fb04be pngdec: Avoid a double-free. dcbb1ca add WebPBlendAlpha() function to blend colors against background bc9f5fb configure.ac: add AM_PROG_AR for automake >= 1.12 bf867bf Tuned cross_color parameter (step) for lower qual 90e2ec5 Merge "probe input file and quick-check for WebP format." 7180d7f Merge "update copyright text" 830f72b probe input file and quick-check for WebP format. 2ccf58d configure: improve gl/glut library test d640614 update copyright text c2113ad Merge "configure: remove use of AS_VAR_APPEND" 9326a56 configure: remove use of AS_VAR_APPEND ea63d61 fix a type warning on VS9 x86 bec1109 fix EXIF parsing in PNG b6e65f3 Merge "fix warnings for vs9 x64" 438946d fix warnings for vs9 x64 f4710e3 collect macroblock reconstruction data in VP8MBData struct 23d28e2 add doc precision for WebPPictureCopy() and WebPPictureView() 518f2cd cosmetics: gif2webp: fix indent af358e6 Merge "remove datatype qualifier for vmnv" 3fe9163 remove datatype qualifier for vmnv 764fdff fix a memory leak in gif2webp 3e59a74 fix two minor memory leaks in webpmux 47b9862 Merge "README: update swig notes" 325d15f remove some cruft from swig/libwebp.jar 4a7627c README: update swig notes 5da81e3 Merge "swig/python: add minimal documentation" f39e08f Merge "swig: add python encode support" 6ca4a3e Merge "swig/java: reduce wrapper function code duplication" 8f8702b Merge "swig/java: rework uint8_t typemap" 91413be reduce memory for VP8MB and remove bitfields use 7413394 Fix the memory leak in ApplyFilters. 2053c2c simplify the alpha-filter testing loop 825b64d swig/python: add minimal documentation 14677e1 swig: add python encode support a5c297c swig/java: reduce wrapper function code duplication ad4a367 swig/java: rework uint8_t typemap 0d25876 use uint8_t for inv_palette[] afa3450 Fix the bug in ApplyPalette. 2d6ac42 Merge "webp/lossless: fix big endian BGRA output" 2ca8396 webp/lossless: fix big endian BGRA output 742110c Speed up ApplyPalette for ARGB pixels. 2451e47 misc code cleanup 83db404 Merge "swig: add python (decode) support" eeeea8b Merge "swig: cosmetics" d5f9b8f Merge "libwebp: fix vp8 encoder mem alloc offsetting" d8edd83 libwebp: fix vp8 encoder mem alloc offsetting 8983b83 remove use of bit-fields in VP8FInfo 87a4fca remove some warnings: ba8f74e Merge "fix for big-endian" a65067f Merge "Further reduce memory to decode lossy+alpha images" 64c8448 Further reduce memory to decode lossy+alpha images 332130b Mux: make a few methods static 4437061 fix for big-endian 5199eab Merge "add uncompressed TIFF output support" a3aede9 add uncompressed TIFF output support f975b67 Merge "gif2webp: Fix signed/unsigned comparison mismatch" 5fbc734 Merge "GetFeatures: Detect invalid VP8X/VP8/VP8L data" d5060c8 Merge "mux.h: A comment fix + some consistency fixes" 352d0de GetFeatures: Detect invalid VP8X/VP8/VP8L data 3ef79fe Cosmetic: "width * height" 043e1ae gif2webp: Fix signed/unsigned comparison mismatch 5818cff mux.h: A comment fix + some consistency fixes 1153f88 Merge "swig: ifdef some Java specific code" 3eeedae Makefile.vc: fix libwebpdemux dll variable typo f980faf swig: add python (decode) support 7f5f42b swig: cosmetics 8eae188 WebP-Lossless encoding improvements. c7247c4 swig: ifdef some Java specific code 4cb234d Merge "Mux: make ValidateForSingleImage() method static" ed6f530 Merge "Add GetCanvasSize() method to mux" 1d530c9 Mux: make ValidateForSingleImage() method static bba4c2b configure: add warning related flags fffefd1 Add GetCanvasSize() method to mux 732da8d Merge "configure: add GLUT detection; build vwebp" 0e513f7 configure: add GLUT detection; build vwebp 55d1c15 Merge "Alpha decoding: significantly reduce memory usage" 13d99fb Merge "configure: add --enable-everything" 2bf698f Merge "configure.ac: add some helper macros" edccd19 Alpha decoding: significantly reduce memory usage 3cafcc9 configure: add --enable-everything 4ef1447 configure.ac: add some helper macros a4e1cdb Remove the gcc compilation comments 6393fe4 Cosmetic fixes 9c4ce97 Simplify forward-WHT + SSE2 version 878b9da fix missed optim 0004617 VP8GetInfo(): Check for zero width or height. 9bf3129 align VP8Encoder::nz_ allocation 5da165c fix CheckMode() signature 0ece07d Merge "explicitly pad bitfields to 32-bits" 9dbc9d1 explicitly pad bitfields to 32-bits 5369a80 Merge "prevent signed int overflow in left shift ops" 70e3971 Merge "cosmetics: remove unnecessary ';'s" d3136ce Merge "don't forward declare enums" b26e5ad gif2webp: Fix ICC and XMP support 46089b2 Add missing name to AUTHORS 94328d6 Demux: Fix a potential memleak 96e948d don't forward declare enums f4f9088 prevent signed int overflow in left shift ops 0261545 cosmetics: remove unnecessary ';'s 7ebdf11 Merge "Fix few missing comparisons to NULL" 1579989 Fix few missing comparisons to NULL ea1b21c Cleaned up VP8GetHeaders() so that it parses only frame header b66caee dwebp: add support for BMP output ff885bf add precision about dynamic output reallocation with IDecoder 79241d5 Merge "Makefile.vc: have 'all' target build everything" ac1c729 Merge "Makefile.vc: flags cleanup" 118a055 Merge "Makefile.vc: drop /FD flag" ecad010 Merge "update gitignore" a681b4f Rename PRE_VP8 state to WEBP_HEADER ead4d47 Add incremental support for extended format files 69d0f92 Makefile.vc: have 'all' target build everything 5296749 Makefile.vc: flags cleanup c61baf0 Makefile.vc: drop /FD flag 3a15125 update gitignore 5167ca4 Merge "WebPEncode: An additional check. Start VP8EncLoop/VP8EncTokenLoop only if VP8EncStartAlpha succeeded." 67708d6 WebPEncode: An additional check. Start VP8EncLoop/VP8EncTokenLoop only if VP8EncStartAlpha succeeded. b68912a pngdec: Avoid a double-free. 82abbe1 Merge "configure.ac: add AM_PROG_AR for automake >= 1.12" e7d9548 add WebPBlendAlpha() function to blend colors against background ed4dc71 configure.ac: add AM_PROG_AR for automake >= 1.12 df4a406 Merge branch '0.3.0' 1e0d4b8 Update ChangeLog (tag: v0.3.0-rc7, tag: v0.3.0) d52b405 Cosmetic fixes 6cb4a61 misc style fix 68111ab add missing YUVA->ARGB automatic conversion in WebPEncode() e9a7990 Cosmetic fixes 403bfe8 Container spec: Clarify frame disposal 2aaa423 Merge "add missing YUVA->ARGB automatic conversion in WebPEncode()" 07d87bd add missing YUVA->ARGB automatic conversion in WebPEncode() 142c462 misc style fix 3e7a13a Merge "Container spec: clarify the background color field" into 0.3.0 14af774 container doc: add a note about the 'ANMF' payload cc635ef Container spec: clarify the background color field e3e3394 container doc: move RIFF description to own section 4299f39 libwebp/mux: fix double free 33f9a69 Merge "demux: keep a frame tail pointer; used in AddFrame" into 0.3.0 a2a7b95 use WebPDataCopy() instead of re-coding it. 6f18f12 demux: keep a frame tail pointer; used in AddFrame e5af49e add doc precision about WebPParseHeaders() return codes db46daa Merge "Makefile.vc: fix dynamic builds" into 0.3.0 53c77af Merge "gif2webp: Bgcolor fix for a special case" into 0.3.0 a5ebd14 gif2webp: Bgcolor fix for a special case 6378f23 Merge "vwebp/animation: fix background dispose" into 0.3.0 3c8eb9a fix bad saturation order in QuantizeBlock 04c7a2e vwebp/animation: fix background dispose 81a5069 Makefile.vc: fix dynamic builds 5f25c39 update ChangeLog (tag: v0.3.0-rc6) 14d42af examples: don't use C99 %zu 5ccf1fe update ChangeLog 2560c24 update NEWS f43bafc Merge changes Iecccb09c,If5ee9fd2,I3e181ce4 into 0.3.0 a788644 dwebp: warn when decoding animated webp's 302efcd Decode: return more meaningful error for animation ad45273 WebPBitstreamFeatures: add has_animation field 783dfa4 disable FRGM decoding for good in libwebpmux 4b956be Update ChangeLog ad8b86d update NEWS 3e084f6 Merge "demux cosmetics: comments/rename internal function" into 0.3.0 d3f8c62 Merge "move WebPFeatureFlags declaration" into 0.3.0 7386fe5 Merge "libwebp{demux,mux}: install mux_types.h" into 0.3.0 d6cd4e9 Merge "bump decode abi" into 0.3.0 17f8da5 bump decode abi 97684ae Merge "add doc precision about WebPDemuxPartial()" into 0.3.0 f933fd2 move WebPFeatureFlags declaration 289bc47 libwebp{demux,mux}: install mux_types.h 224e8d4 add doc precision about WebPDemuxPartial() 4c18e80 demux cosmetics: comments/rename internal function 7cfd1bf update AUTHORS 401f7b8 Merge "speed-up lossless (~3%) with ad-hoc histogram cost evaluation" into 0.3.0 1fc8ffc Merge "makefile.unix: dist related changes" into 0.3.0 8a89c6e Merge changes I466c377f,Ib761ebd3,I694857fc into 0.3.0 f4ffb2d speed-up lossless (~3%) with ad-hoc histogram cost evaluation 723847d gif2webp: only write error messages to stderr 701b9e2 makefile.unix: dist related changes bb85b43 Merge "update NEWS" into 0.3.0 59423a2 gif2webp: fix crash on open failure with libgif5 9acb17d gif2webp: silence a unused param warning 7d9fdc2 Merge "README updates" into 0.3.0 5621934 Merge "build: fix install race on shared headers" into 0.3.0 70809d8 Merge "bump version to 0.3.0" into 0.3.0 d851cd1 demux: make the parse a bit more strict 28bb410 update NEWS cef9388 bump version to 0.3.0 9048494 build: fix install race on shared headers 1e67e8e README updates 42b611a Merge "configure: drop experimental from mux/demux" into 0.3.0 096a8e3 Merge "vwebp: add color profile support" into 0.3.0 ddfee5d vwebp: add color profile support 0d6927d Merge "Mark fragment options as experimental in webpmux" into 0.3.0 5dbd403 Mark fragment options as experimental in webpmux a0a6648 configure: drop experimental from mux/demux ee65bad Merge "add support for BITS > 32" into 0.3.0 744930d add support for BITS > 32 7dd288f cwebp: fix build 19a8dd0 Merge "Makefile.vc: add vwebp.exe target" into 0.3.0 50eedda Merge "examples: normalize icc related program arguments" into 0.3.0 757f637 Merge "Makefile.vc: add libwebpdecoder target" into 0.3.0 b65c4b7 Makefile.vc: add libwebpdecoder target f8db7b4 Merge "vwebp: replace doubles w/floats where appropriate" into 0.3.0 d99aa56 Makefile.vc: add vwebp.exe target 013023e vwebp: replace doubles w/floats where appropriate 9b3db89 README.mux: add version reference 7b6a26c Merge "cwebp: output metadata statistics" into 0.3.0 d8dc72a examples: normalize icc related program arguments 7bfc905 Merge "make alpha unfilter work in-place" into 0.3.0 0037b2d Merge "add LUT-free reference code for YUV->RGB conversion." into 0.3.0 166bf74 Merge "demux: disable fragment parsing" into 0.3.0 126974b add LUT-free reference code for YUV->RGB conversion. 0aef3eb make alpha unfilter work in-place 14ef500 Merge "Remove 'status: experimental' from container spec" into 0.3.0 d40c98e Merge "webpmux binary: tiny style fix" into 0.3.0 0bc4268 cwebp: output metadata statistics bc03980 Merge "autoconf: normalize experimental define" into 0.3.0 d1e21b1 Remove 'status: experimental' from container spec 7681bb9 webpmux binary: tiny style fix a3dd3d0 avoid installing example_util.h 252320e demux: disable fragment parsing 537bde0 autoconf: normalize experimental define 5e338e0 Merge changes I33e8a613,I8e8a7b44 into 0.3.0 d9d0ea1 Merge changes If21e3ec7,I991fc30b into 0.3.0 627f5ca automake: add reference to libwebp for mux/demux eef73d0 don't consolidate proba stats too often 05ec4cc libwebp{,decoder}.pc: add pthread flags 1bfcf5b add libwebpmux.pc 26ca843 add libwebpdemux.pc 69e2590 Merge "Tune Lossless compression for lower qualities." 0478b5d Tune Lossless compression for lower qualities. 39f7586 add a mention of parallel alpha encoding in the NEWS 5a21d96 Merge "1.5x-2x faster encoding for method 3 and up" 9bfbdd1 1.5x-2x faster encoding for method 3 and up 27dc741 Correct frame options order in README.mux be2fd17 Mux: fix a scenario with bad ANMF/FRGM size 19eb012 Merge "Demux: Add option to get frame count using GetI()" 7368b8c Merge "WebPGetFeatures() out of if condition for clarity." f604c9a Merge "fix windows build" 153f94e fix windows build 847b492 Merge "vwebp: use magenta for 'i'nfo display" 25ea46b Merge "vwebp: add keyboard shortcuts to help output" bea7cca vwebp: use magenta for 'i'nfo display 8fab161 webpmux: correct -frame param order in help output 03cc23d vwebp: add keyboard shortcuts to help output 068eba8 Demux: Add option to get frame count using GetI() 988b8f5 WebPGetFeatures() out of if condition for clarity. 6933d91 Merge "gif2webp: Be lenient about background color index." 4d0f7c5 Merge "WebPGetFeatures() behavior change:" fdeeb01 gif2webp: Be lenient about background color index. ad25032 Merge "multi-threaded alpha encoding for lossy" 4e32d3e Merge "fix compilation of token.c" f817930 multi-threaded alpha encoding for lossy 8805035 fix compilation of token.c fc81621 code using the actual values for num_parts_, not the ones from config 7265535 Merge "move the config check from .c to .h" dd9e76f move the config check from .c to .h 956b217 WebPGetFeatures() behavior change: df02e4c WebPDemuxGetI behavior change: 633c004 Merge "rebalance method tools (-m) for methods [0..4]" 58ca6f6 rebalance method tools (-m) for methods [0..4] 7648c3c Merge "describe rd-opt levels introduce VP8RDLevel enum" 67fb100 Merge "autoconf: enable silent-rules by default" a5042a3 GetVersion() methods for mux and demux 5189957 describe rd-opt levels introduce VP8RDLevel enum 4e094ac autoconf: enable silent-rules by default b7eaa85 inline VP8LFastLog2() and VP8LFastSLog2 for small values 5cf7792 split quant_levels.c into decoder and encoder version e5d3ffe Merge "Update code example in README.mux" ac5a915 Update code example in README.mux 38a91e9 Add example code snippet for demux API 5f557f3 README.mux: add info about Demux API and vwebp c0ba090 backward_references: avoid signed integer overflow 943386d disable SSE2 for now 9479fb7 lossless encoding speedup ec2030a merge two lines together b67956c Merge "Remove ReadOneBit() and ReadSymbolUnsafe()" 1667bde Remove ReadOneBit() and ReadSymbolUnsafe() 3151669 wicdec + dwebp cosmetics: normalize formatting 92668da change default filtering parameters: * type is now 'strong' * strength is now '60' b7490f8 introduce WEBP_REFERENCE_IMPLEMENTATION compile option 3383885 faster decoding (3%-6%) 5c3e381 Merge "add a -jpeg_like option" c231104 remove unused declaration of VP8Zigzag 3615295 Merge "wicdec: add alpha support for paletted formats" c9f1649 wicdec: add alpha support for paletted formats 1262f81 Merge "wicdec: silence some warnings" e7ea61e wicdec: silence some warnings 23c0f35 fix missing intptr_t->int cast for MSVC e895059 add a -jpeg_like option 1f803f6 Merge "Tune alpha quality mapping to more reasonable values." 1267d49 Tune alpha quality mapping to more reasonable values. 043076e Merge "speed-up lossless in BackwardTrace" f3a44dc remove one malloc from TraceBackwards() 0fc1a3a speed-up lossless in BackwardTrace 7c732e5 cwebp: centralize WebPCleanupTransparentArea() 7381254 Merge "wicdec: add ICC profile extraction" e83ff7d wicdec: add ICC profile extraction 146c6e3 Merge "cosmetics: pngdec: normalize default label location" a8f549d Merge "manpages: italicize option parameters" e118db8 Merge "encode.h: note the need to free() WebPMemoryWriter" 1dfee6d cosmetics: pngdec: normalize default label location 14c3820 manpages: italicize option parameters 7defbfa encode.h: note the need to free() WebPMemoryWriter 88d382a cwebp: cleanup after memory_writer 12d6cec fix extra space in dwebp.1 man b01681a Fix for demuxer frame iteration: 56c12aa Demuxer creation fix: 66c810b add a -yuv option to dwebp (very similar to -pgm) 841a3ba Merge "Remove -Wshadow warnings." 8fd0252 Merge "upsampling_neon.c: fix build" 6efed26 Remove -Wshadow warnings. 60904aa Merge "allow WebPINewRGB/YUVA to be passed a NULL output buffer." b7adf37 allow WebPINewRGB/YUVA to be passed a NULL output buffer. 27f8f74 upsampling_neon.c: fix build 06b9cdf gitignore: add IOS related directories f112221 Merge "Fix more comments for iobuild.sh" fe4d25d Fix more comments for iobuild.sh 1de3e25 Merge "NEON optimised yuv to rgb conversion" 090b708 NEON optimised yuv to rgb conversion daa0647 Merge "Add ios build script for building iOS library." 79fe39e Add ios build script for building iOS library. 126c035 remove some more -Wshadow warnings 522e9d6 Merge "cwebp: enable '-metadata'" 76ec5fa cwebp: enable '-metadata' aeb91a9 Merge "cosmetics: break a few long lines" be7c96b cosmetics: break a few long lines cff8ddb Merge "add libwebpdecoder.pc" 93148ab Merge "libwebp.pc.in: detab" 6477f95 Merge "Makefile.vc: normalize path separator" bed1ed7 add libwebpdecoder.pc 46168b2 libwebp.pc.in: detab a941a34 Fixed few nits in the build files. dd7a49b Makefile.vc: normalize path separator 9161be8 Merge "cwebp: extract WIC decoding to its own module" 08e7c58 Merge "Provide an option to build decoder library." 0aeba52 Provide an option to build decoder library. 757ebcb catch malloc(0)/calloc(0) with an assert 152ec3d Merge "handle malloc(0) and calloc(0) uniformly on all platforms" a452a55 cwebp: extract WIC decoding to its own module 2b252a5 Merge "Provide option to swap bytes for 16 bit colormodes" 94a48b4 Provide option to swap bytes for 16 bit colormodes 42f8f93 handle malloc(0) and calloc(0) uniformly on all platforms 8b2152c Merge "add an extra assert to check memory bounds" 0d19fbf remove some -Wshadow warnings cd22f65 add an extra assert to check memory bounds 8189fed Merge "Add details and reference about the YUV->RGB conversion" 1d2702b Merge "Formatting fixes in lossless bitstream spec" 8425aae Formatting fixes in lossless bitstream spec a556cb1 Add details and reference about the YUV->RGB conversion d8f21e0 add link to SSIM description on Wikipedia 18e9167 Merge "WebP-lossless spec clarifications:" 98e25b9 Merge "cwebp: add -metadata option" f01c2a5 WebP-lossless spec clarifications: f4a9797 Merge "Disto4x4 and Disto16x16 in NEON" 47b7b0b Disto4x4 and Disto16x16 in NEON 7eaee9f cwebp: add -metadata option 36c52c2 tiffdec: use toff_t for exif ifd offset 7c8111e Merge "cwebp/tiffdec: add TIFF metadata extraction" e6409ad Remove redundant include from dsp/lossless code. 1ab5b3a Merge "configure: fix --with-gifincludedir" 03c749e configure: fix --with-gifincludedir 8b65063 multiple libgif versions support for gif2webp 476e293 gif2webp: Use DGifOpenFileName() b50f277 tiffdec: correct format string 2b9048e Merge "tiffdec: check error returns for width/height" a1b5a9a Merge "cwebp/tiff: use the first image directory" 079423f tiffdec: check error returns for width/height d62824a Merge "cwebp/jpegdec: add JPEG metadata extraction" 03afaca Merge "cwebp: add PNG metadata extraction" 2c72496 cwebp/jpegdec: add JPEG metadata extraction dba64d9 cwebp: add PNG metadata extraction 1f075f8 Lossless spec corrections/rewording/clarifications 2914ecf cwebp/tiffdec: add TIFF metadata extraction d82a3e3 More corrections/clarifications in lossless spec: bd00255 cwebp/tiff: use the first image directory df7aa07 Merge "Cleanup around jpegdec" 0f57dcc decoding speed-up (~1%) bcec339 Lossless bitstream clarification: 6bf2087 add examples/metadata.c 207f89c Merge "configure: add libwebpdemux status to summary" 1bd287a Cleanup around jpegdec 9145567 Merge "cosmetics: use '== 0' in size checks" d6b88b7 cosmetics: use '== 0' in size checks d3dace2 cosmetics: jpegdec 2f69af7 configure: add libwebpdemux status to summary 1c1c564 cwebp: extract tiff decoding to its own module 6a871d6 cwebp: extract jpeg decoding to its own module 2ee228f cwebp: extract png decoding to its own module 4679db0 Merge "cwebp: add metadata framework" 63aba3a cwebp: add metadata framework 931bd51 lossless bitstream: block size bits correction e4fc4c1 lossless bitstream: block size bits correction d65ec67 fix build, move token.c to src/enc/ 657f5c9 move token buffer to its own file (token.c) c34a375 introduce GetLargeValue() to slim-fast GetCoeffs(). d5838cd faster non-transposing SSE2 4x4 FTransform f76191f speed up GetResidualCost() ba2aa0f Add support for BITS=24 case 2e7f6e8 makefile.unix: Dependency on libraries dca8421 Merge "Separate out mux and demux code and libraries:" 23782f9 Separate out mux and demux code and libraries: bd56a01 configure: add summary output 90e5e31 dwebp manual: point to webpmux, gif2webp. 540790c gif2webp.c: add a note about prerequisites d1edf69 cwebp man page: meaning of '-q' for lossy/lossless 79efa1d Add man page for gif2webp utility 2243e40 Merge "gif2webp build support with autoconf tools" c40efca gif2webp build support with autoconf tools 6523e2d WebP Container: 4da788d Merge "simplify the fwd transform" 42c3b55 simplify the fwd transform 41a6ced user GLfloat instead of float b542611 fix indentation 68f282f * handle offset in anim viewer 'vwebp' * fix gif2webp to handle disposal method and odd offset correctly 118cb31 Merge "add SSE2 version of Sum of Square error for 16x16, 16x8 and 8x8 case" 8a7c3cc Merge "Change the order of -frame argument to be more natural" 99e0a70 Merge "Simplify the texture evaluation Disto4x4()" 0f923c3 make the bundling work in a tmp buffer e5c3b3f Simplify the texture evaluation Disto4x4() 4860008 Change the order of -frame argument to be more natural 35bfd4c add SSE2 version of Sum of Square error for 16x16, 16x8 and 8x8 case a7305c2 Clarification for unknown chunks 4c4398e Refine WebP Container Spec wrt unknown chunks. 2ca642e Rectify WebPMuxGetFeatures: 7caab1d Some cosmetic/comment fixes. 60b2651 Merge "Write a GIF to WebP converter based on libgif." c7127a4 Merge "Add NEON version of FTransformWHT" 11b2721 Write a GIF to WebP converter based on libgif. e9a15a3 ExUtilWriteFile() to write memory segment to file 74356eb Add a simple cleanup step in mux assembly: 51bb1e5 mux.h: correct WebPDemuxSelectFragment() prototype 22a0fd9 Add NEON version of FTransformWHT fa30c86 Update mux code to match the spec wrt animation d9c5fbe by-pass Analysis pass in case segments=1 d2ad445 Merge changes Ibeccffc3,Id1585b16 5c8be25 Merge "Chunk fourCCs for XMP/EXIF" a00a3da Use 'frgm' instead of 'tile' in webpmux parameters 81b8a74 Design change in ANMF and FRGM chunks: f903cba Chunk fourCCs for XMP/EXIF 812933d Tune performance of HistogramCombine 52ad197 Animation specification in container spec 001b930 Image fragment specification in container spec 391f9db Ordering of description of bits in container spec d573577 Metadata specification in container spec 1c4609b Merge commit 'v0.2.1' 0ca584c Merge "Color profile specification in container spec" e8b41ad add NEON asm version for WHT inverse transform af6f0db Color profile specification in container spec a61a824 Merge "Add NULL check in chunk APIs" 0e8b7ee fix WebPPictureView() unassigned strides 75e5f17 ARM/NEON: 30% encoding speed-up 02b4356 Add NULL check in chunk APIs a077072 mux struct naming 6c66dde Merge "Tune Lossless encoder" ab5ea21 Tune Lossless encoder 74fefc8 Update ChangeLog (tag: v0.2.1, origin/0.2.0, 0.2.0) 92f8059 Rename some chunks: 3bb4bbe Merge "Mux API change:" d0c79f0 Mux API change: abc0604 Merge "update NEWS" into 0.2.0 57cf313 update NEWS 25f585c bump version to 0.2.1 fed7c04 libwebp: validate chunk size in ParseOptionalChunks 552cd9b cwebp (windows): fix alpha image import on XP b14fea9 autoconf/libwebp: enable dll builds for mingw 4a8fb27 [cd]webp: always output windows errors d662158 fix double to float conversion warning 72b96a6 cwebp: fix jpg encodes on XP 734f762 VP8LAllocateHistogramSet: fix overflow in size calculation f9cb58f GetHistoBits: fix integer overflow b30add2 EncodeImageInternal: fix uninitialized free 3de58d7 fix the -g/O3 discrepancy for 32bit compile 77aa7d5 fix the BITS=8 case e5970bd Make *InitSSE2() functions be empty on non-SSE2 platform ef5cc47 make *InitSSE2() functions be empty on non-SSE2 platform c4ea259 make VP8DspInitNEON() public 8344ead Merge "libwebp: validate chunk size in ParseOptionalChunks" 4828bb9 Merge "cwebp (windows): fix alpha image import on XP" 3076333 libwebp: validate chunk size in ParseOptionalChunks 7048189 AccumulateLSIM: fix double -> float warnings eda8ee4 cwebp (windows): fix alpha image import on XP c6e9865 Merge "add EXPERIMENTAL code for YUV-JPEG colorspace" f0360b4 add EXPERIMENTAL code for YUV-JPEG colorspace f86e6ab add LSIM metric to WebPPictureDistortion() c3aa215 Speed up HistogramCombine for lower qualities. 1765cb1 Merge "autoconf/libwebp: enable dll builds for mingw" a13562e autoconf/libwebp: enable dll builds for mingw 9f469b5 typo: no_fancy -> no_fancy_upsampling 1a27f2f Merge "fix double to float conversion warning" cf1e90d Merge "cwebp: fix jpg encodes on XP" f2b5d19 [cd]webp: always output windows errors e855208 fix double to float conversion warning ecd66f7 cwebp: fix jpg encodes on XP 7b3eb37 Tune lossless compression to get better gains. ce8bff4 Merge "VP8LAllocateHistogramSet: fix overflow in size calculation" ab5b67a Merge "EncodeImageInternal: fix uninitialized free" 7fee5d1 Merge "GetHistoBits: fix integer overflow" a6ae04d VP8LAllocateHistogramSet: fix overflow in size calculation 80237c4 GetHistoBits: fix integer overflow 8a99723 EncodeImageInternal: fix uninitialized free 0b9e682 minor cosmetics a792b91 fix the -g/O3 discrepancy for 32bit compile 73ba435 Merge "detect and merge similar segments" fee6627 detect and merge similar segments 0c44f41 src/webp/*.h: don't forward declare enums in C++ d7a5ac8 vwebp: use demux interface 931e0ea Merge "replace 'typedef struct {} X;" by "typedef struct X X; struct X {};"" 8f216f7 remove cases of equal comparison for qsort() 28d25c8 replace 'typedef struct {} X;" by "typedef struct X X; struct X {};" 2afee60 speed up for ARM using 8bit for boolean decoder 5725cab new segmentation algorithm 2cf1f81 Merge "fix the BITS=8 case" 12f78ae fix the BITS=8 case 6920c71 fix MSVC warnings regarding implicit uint64 to uint32 conversions f6c096a webpmux binary: Rename 'xmp' option to 'meta' ddfe871 webpmux help correction b7c5544 Merge "Make *InitSSE2() functions be empty on non-SSE2 platform" 1c04a0d Common APIs for chunks metadata and color profile. 2a3117a Merge "Create WebPMuxFrameInfo struct for Mux APIs" 5c3a723 Make *InitSSE2() functions be empty on non-SSE2 platform 7c6e60f make *InitSSE2() functions be empty on non-SSE2 platform c7eb457 make VP8DspInitNEON() public ab3234a Create WebPMuxFrameInfo struct for Mux APIs e3990fd Alignment fixes e55fbd6 Merge branch '0.2.0' 4238bc0 Update ChangeLog (tag: v0.2.0) c655380 dec/io.c: cosmetics fe1958f RGBA4444: harmonize lossless/lossy alpha values 681cb30 fix RGBA4444 output w/fancy upsampling f06c1d8 Merge "Alignment fix" into 0.2.0 f56e98f Alignment fix 6fe843b avoid rgb-premultiply if there's only trivial alpha values 528a11a fix the ARGB4444 premultiply arithmetic a0a4885 Lossless decoder fix for a special transform order 62dd9bb Update encoding heuristic w.r.t palette colors. 6f4272b remove unused ApplyInverseTransform() 93bf0fa Update ChangeLog (tag: v0.2.0-rc1) 5934fc5 update AUTHORS 014a711 update NEWS 43b0d61 add support for ARGB -> YUVA conversion for lossless decoder 33705ca bump version to 0.2.0 c40d7ef fix alpha-plane check + add extra checks a06f802 MODE_YUVA: set alpha to opaque if the image has none 52a87dd Merge "silence one more warning" into 0.2.0 3b02309 silence one more warning f94b04f move some RGB->YUV functions to yuv.h 4b71ba0 README: sync [cd]webp help output c9ae57f man/dwebp.1: add links to output file format details 292ec5c quiet a few 'uninitialized' warnings 4af3f6c fix indentation 9b261bf remove the last NOT_HAVE_LOG2 instances 323dc4d remove use of log2(). Use VP8LFastLog2() instead. 8c515d5 Merge "harness some malloc/calloc to use WebPSafeMalloc and WebPSafeCalloc" into 0.2.0 d4b4bb0 Merge changes I46090628,I1a41b2ce into 0.2.0 bff34ac harness some malloc/calloc to use WebPSafeMalloc and WebPSafeCalloc a3c063c Merge "extra size check for security" into 0.2.0 5e79630 Merge "WebPEncode: clear stats at the start of encode" into 0.2.0 f1edf62 Merge "rationalize use of color-cache" into 0.2.0 c193331 extra size check for security 906be65 rationalize use of color-cache dd1c387 Add image-hint for low-color images. 4eb7aa6 Merge "WebPCheckMalloc() and WebPCheckCalloc():" into 0.2.0 80cc730 WebPCheckMalloc() and WebPCheckCalloc(): 183cba8 check VP8LBitWriterInit return cbfa9ee lossless: fix crash on user abort 256afef cwebp: exit immediately on version mismatch 475d87d WebPEncode: clear stats at the start of encode a7cc729 fix type and conversion warnings 7d853d7 add stats for lossless d39177b make QuantizeLevels() store the sum of squared error 5955cf5 replace x*155/100 by x*101581>>16 7d732f9 make QuantizeLevels() store the sum of squared error e45a446 replace x*155/100 by x*101581>>16 159b75d cwebp output size consistency: cbee59e Merge commit 'v0.1.99' 1889e9b dwebp: report -alpha option 3bc3f7c Merge "dwebp: add PAM output support" into 0.2.0 d919ed0 dwebp: add PAM output support 85e215d README/manpages/configure: update website link c3a207b Update ChangeLog (tag: v0.1.99) d1fd782 Merge "add extra precision about default values and behaviour" into 0.2.0 efc826e add extra precision about default values and behaviour 9f29635 header/doc clean up ff9fd1b Makefile.vc: fix webpmux.exe *-dynamic builds 8aacc7b remove INAM, ICOP, ... chunks from the test webp file. 2fc1301 harmonize authors as "Name (mail@address)" 4a9f37b Merge "update NEWS" into 0.2.0 7415ae1 makefile.unix: provide examples/webpmux target ce82ced update NEWS 641e28e Merge "man/cwebp.1: wording, change the date" into 0.2.0 c37c23e README: cosmetics 3976dcd man/cwebp.1: wording, change the date 3e5bbe1 Merge "rename 'use_argb_input' to 'use_argb'" into 0.2.0 ce90847 Merge "add some padding bytes areas for later use" into 0.2.0 2390dab Merge "fixing the findings by Frederic Kayser to the bitstream spec" into 0.2.0 0275159 add a very crude progress report for lossless a4b9b1c Remove some unused enum values. dd10817 rename 'use_argb_input' to 'use_argb' 90516ae add some padding bytes areas for later use d03b250 fixing the findings by Frederic Kayser to the bitstream spec ce156af add missing ABI compatibility checks 9d45416 Merge "Doc: container spec text tweaks" into 0.2.0 4e2e0a8 Doc: container spec text tweaks f7f16a2 add ABI compatibility check 2a77557 Merge "swig: add WebPEncodeLossless* wrappers" into 0.2.0 a3ec622 mux.h: remove '* const' from function parameters 31426eb encode.h: remove '* const' from function parameters 9838e5d decode.h: remove '* const' from function parameters 4972302 swig: add WebPEncodeLossless* wrappers 9ff00ca bump encoder/decoder versions c2416c9 add lossless quick encoding functions to the public API 4c1f5d6 Merge "NEWS: mention decode_vp8.h is no longer installed" into 0.2.0 6cb2277 NEWS: mention decode_vp8.h is no longer installed d5e5ad6 move decode_vp8.h from webp/ to dec/ 8d3b04a Merge "header clean-up" into 0.2.0 02201c3 Merge "remove one malloc() by making color_cache non dynamic" into 0.2.0 d708ec1 Merge "move MIN/MAX_HISTO_BITS to format_constants.h" into 0.2.0 ab2da3e Merge "add a malloc() check" into 0.2.0 2d571bd add a malloc() check 7f0c178 remove one malloc() by making color_cache non dynamic 6569cd7 Merge "VP8LFillBitWindow: use 64-bit path for msvc x64 builds" into 0.2.0 23d34f3 header clean-up 2a3ab6f move MIN/MAX_HISTO_BITS to format_constants.h 985d3da Merge "shuffle variables in HashChainFindCopy" into 0.2.0 cdf885c shuffle variables in HashChainFindCopy c3b014d Android.mk: add missing lossless files 8c1cc6b makefile.unix dist: explicitly name installed includes 7f4647e Merge "clarify the colorspace naming and byte ordering of decoded samples" into 0.2.0 cbf6972 clarify the colorspace naming and byte ordering of decoded samples 857650c Mux: Add WebPDataInit() and remove WebPImageInfo ff771e7 don't install webp/decode_vp8.h 596dff7 VP8LFillBitWindow: use 64-bit path for msvc x64 builds 3ca7ce9 Merge "doc: remove non-finalized chunk references" into 0.2.0 1efaa5a Merge "bump versions" into 0.2.0 51fa13e Merge "README: update cwebp help output" into 0.2.0 12f9aed README: update cwebp help output f0b5def bump versions 4c42a61 update AUTHORS 6431a1c doc: remove non-finalized chunk references 8130c4c Merge "build: remove libwebpmux from default targets/config" 23b4443 Merge "configure: broaden test for libpng-config" 85bff2c Merge "doc: correct lossless prefix coding table & code" 05108f6 Merge "More spec/code matching in mux:" 6808e69 More spec/code matching in mux: bd2b46f Merge "doc/webp-container-spec: light cosmetics" 20ead32 doc/webp-container-spec: light cosmetics 1d40a8b configure: add pthread detection b5e9067 fix some int <-> size_t mix for buffer sizes e41a759 build: remove libwebpmux from default targets/config 0fc2baa configure: broaden test for libpng-config 45b8272 Merge "restore authorship to lossless bitstream doc" 06ba059 restore authorship to lossless bitstream doc 44a09a3 add missing description of the alpha filtering methods 63db87d Merge "vwebp: add checkboard background for alpha display" a73b897 vwebp: add checkboard background for alpha display 939158c Merge "vwebp: fix info display" b35c07d vwebp: fix info display 48b39eb fix underflow for very short bitstreams 7e62298 cosmetics: param alignment, manpage wording 1bd7dd5 Merge changes I7b0afb0d,I7ecc9708 ac69e63 Merge "Updated cwebp man's help for Alpha & Lossless." c0e8859 Get rid of image_info_ from WebPChunk struct. 135ca69 WebP Container Spec: eb6f9b8 Updated cwebp man's help for Alpha & Lossless. 0fa844f cosmetic fixes on assert and 'const' where applicable 7f22bd2 check limit of width * height is 32 bits 16c46e8 autoconf/make: cosmetics: break long lines ab22a07 configure: add helper macro to define --with-* c17699b configure: add libtiff test 0e09732 Merge "cwebp: fix crash with yuv input + lossless" 88a510f Merge "fix big-endian VP8LWriteBits" da99e3b Merge "Makefile.vc: split mux into separate lib" 7bda392 cwebp: fix crash with yuv input + lossless f56a369 fix big-endian VP8LWriteBits 54169d6 Merge "cwebp: name InputFileFormat members consistently" e2feefa Makefile.vc: split mux into separate lib 27caa5a Merge "cwebp: add basic TIFF support" d8921dd cwebp: name InputFileFormat members consistently 6f76d24 cwebp: add basic TIFF support 4691407 Merge changes If39ab7f5,I3658b5ae cca7c7b Fixed nit: 10 -> 10.f 5d09a24 WebPMuxCreate() error handling: 777341c Fix a memleak in WebPMuxCreate() 61c9d16 doc: correct lossless prefix coding table & code 4c39757 Merge "mark VP8{,L}{GetInfo,CheckSignature} as WEBP_EXTERN" e4e36cc Merge "Mux: Allow only some frames/tiles to have alpha." ad2aad3 Merge "WebP Decoding error handling:" 97649c8 Mux: Allow only some frames/tiles to have alpha. f864be3 Lower the quality settings for Alpha encoding. 3ba81bb WebP Decoding error handling: fcc6992 add automatic YUVA/ARGB conversion during WebPEncode() 802e012 fix compilation in non-FANCY_UPSAMPLING mode e012dfd make width/height coding match the spec 228d96a mark VP8{,L}{GetInfo,CheckSignature} as WEBP_EXTERN 637a314 remove the now unused *KeepA variants d11f6fc webpmux returns error strings rather than numbers fcec059 makefile.unix: cwebp: fix OSX link 6b811f1 Merge "doc: remove lossless pdf" c963482 doc: remove lossless pdf b9ae4f0 cosmetics after mux changes b74ed6e, b494ad5 b494ad5 Mux: only allow adding frame/tiles at the end. 2c341b0 Merge "Added image characteristic hint for the codec." d373076 Added image characteristic hint for the codec. 2ed2adb Merge "msvc: add intrinsic based BitsLog2Floor" e595e7c Merge "add demux.c to the makefiles" da47b5b Merge "demux: add {Next,Prev}Chunk" e5f4674 add demux.c to the makefiles 4708393 demux: add {Next,Prev}Chunk e8a0a82 demux: quiet msvc warnings 7f8472a Update the WebP Container Spec. 31b68fe cleanup WebPPicture struct and API 9144a18 add overflow check before calling malloc() 81720c9 consistency cosmetics 2ebe839 Merge "Add kramdown version information to README" 7144308 enc/vp8l.c: fix build b7ac19f Add kramdown version information to README efdcb66 Merge "Edit for consistency, usage and grammar." 0822010 Enable alpha in vvwebp 8de9a08 Merge "Mux API change:" b74ed6e Mux API change: 233a589 take picture->argb_stride into account for lossless coding 04e33f1 Edit for consistency, usage and grammar. a575b4b Merge "cosmetics: add missing const" 8d99b0f Merge "cosmetics: remove unimplemented function proto" 69d0221 cosmetics: add missing const 5b08318 cosmetics: remove unimplemented function proto b7fb0ed Log warning for unsupported options for lossless. e1f769f msvc: add intrinsic based BitsLog2Floor 8a69c7d Bug-fix: Clamp backward dist to 1. b5b6ac9 Merge "Bring the special writer 'WebPMemoryWriter' to public API" a6a1909 Merge "Fix floating point exception with cwebp -progress" f2cee06 Fix floating point exception with cwebp -progress 91b7a8c Bring the special writer 'WebPMemoryWriter' to public API 310e297 support resize and crop for RGBA input a89835d Merge changes Ice662960,Ie8d7aa90,I2d996d5e,I01c04772 ce614c0 Merge "dec/vp8: avoid setting decoder status twice" 900285d dec/vp8: avoid setting decoder status twice 8227adc Merge changes I6f02b0d0,I5cbc9c0a,I9dd9d4ed,Id684d2a1 dcda59c Merge "demux: rename SetTile to SelectTile" 622ef12 demux: rename SetTile to SelectTile 81ebd37 Merge "demux: add {Next,Prev}Frame" 02dd37a demux: add {Next,Prev}Frame 4b79fa5 Merge "Limit the maximum size of huffman Image to 16MB." 9aa34b3 Manually number "chapters," as chapter numbers are used in the narrative. 2a4c6c2 Re-wrap at <= 72 columns a45adc1 Apply inline emphasis and monospacing, per gdoc / PDF 9101120 Incorporate gdoc changes through 2012-06-08 7a18248 Removed CodeRay syntax declarations ... b3ec18c Provide for code-block syntax highlighting. 709d770 Replace high ASCII artifacts (curly quotes, etc.). 930e8ab Lossless WebP doc largely ported to markdown text. 18cae37 msvc: silence some build warnings b392308 Limit the maximum size of huffman Image to 16MB. f180df2 Merge "libwebp/demux: add Frame/Chunk iteration" 2bbe1c9 Merge "Enable lossless encoder code" d0601b0 Merge changes I1d97a633,I81c59093 78f3e34 Enable lossless encoder code d974a9c Merge "libwebp/demux: add simple format parsing" 26bf223 Merge "libwebp: add WebPDemux stub functions" 2f66668 Merge "modify WebPParseHeaders to allow reuse by GetFeatures" b402b1f libwebp/demux: add Frame/Chunk iteration ad9ada3 libwebp/demux: add WebPDemuxGetI 2f2d4d5 libwebp/demux: add extended format parsing 962dcef libwebp/demux: add simple format parsing f8f9408 libwebp: add WebPDemux stub functions fb47bb5 Merge "NumNamedElements() should take an enum param." 7c68980 Fix asserts in Palette and BackwardReference code. fbdcb7e NumNamedElements() should take an enum param. fb4943b modify WebPParseHeaders to allow reuse by GetFeatures 3697b5c write an ad-hoc EncodeImageInternal variant eaee9e7 Bug-Fix: Decode small (less than 32 bytes) images. 0bceae4 Merge "cwebp: fix alpha reporting in stats output" 0424b1e Rebase default encoding settings. c71ff9e cwebp: fix alpha reporting in stats output e2ffe44 Merge "Stop indefinite recursion for Huffman Image." 70eb2bd Stop indefinite recursion for Huffman Image. f3bab8e Update vwebp 6d5c797 Remove support for partial files in Mux. f1df558 WebPMuxAssemble() returns WebPData*. 814a063 Rename 'Add' APIs to 'Set'. bbb0218 Update Mux psuedo-code examples. 4fc4a47 Use WebPData in MUX set APIs c67bc97 Merge "add WebPPictureImportRGBX() and WebPPictureImportBGRX()" 27519bc add WebPPictureImportRGBX() and WebPPictureImportBGRX() f80cd27 factorize code in Import() 9b71502 histogram: add log2 wrapper 8c34378 Merge "fix some implicit type conversion warnings" 42f6df9 fix some implicit type conversion warnings 250c16e Merge "doc: update lossless pdf" 9d9daba Merge "add a PDF of the lossless spec" 8fbb918 prefer webp/types.h over stdint.h 0ca170c doc: update lossless pdf 0862ac6 add a PDF of the lossless spec 437999f introduce a generic WebPPictureHasTransparency() function d2b6c6c cosmetic fixes after Idaba281a b4e6645 Merge "add colorspace for premultiplied alpha" 48f8275 add colorspace for premultiplied alpha 069f903 Change in lossless bit-stream. 5f7bb3f Merge "WebPReportProgress: use non-encoder specific params" f18281f WebPReportProgress: use non-encoder specific params 9ef3228 Add support for raw lossless bitstream in decoder. 7cbee29 Fix bug: InitIo reseting fancy_upsampling flag. 880fd98 vwebp: fix exit w/freeglut 1875d92 trap two unchecked error conditions 87b4a90 no need to have mux.h as noinst clause in enc/ 88f41ec doc: fix bit alignment in VP8X chunk 52f5a4e Merge "fix bug with lossy-alpha output stride" 3bde22d fix bug with lossy-alpha output stride 42d61b6 update the spec for the lossy-alpha compression methods. e75dc80 Move some more defines to format_constants.h c13f663 Move consts to internal header format_constants.h 7f2dfc9 use a bit-set transforms_seen_ instead of looping 18da1f5 modulate alpha-compression effort according to config.method f5f2fff Merge "Alpha flag fix for lossless." c975c44 Alpha flag fix for lossless. 4f067fb Merge "Android: only build dec_neon with NEON support" 255c66b Android: only build dec_neon with NEON support 8f9117a cosmetics: signature fixes 39bf5d6 use header-less lossless bitstream for alpha channel 75d7f3b Merge "make input data be 'const' for VP8LInverseTransform()" 9a721c6 make input data be 'const' for VP8LInverseTransform() 9fc64ed Disallow re-use of same transformation. 98ec717 use a function pointer for ProcessRows() f7ae5e3 cosmetics: join line 140b89a factor out buffer alloc in AllocateARGBBuffers() a107dfa Rectify WebPParseOptionalChunks(). 237eab6 Add two more color-spaces for lossless decoding. 27f417a fix orthographic typo 489ec33 add VP8LEncodeStream() to compress lossless image stream fa8bc3d make WebPEncodingSetError() take a const picture 638528c bitstream update for lossy alpha compression d73e63a add DequantizeLevels() placeholder ec122e0 remove arch-dependent rand() d40e765 fix alignment 1dd6a8b Merge "remove tcoder, switch alpha-plane compression to lossless" 3e863dd remove tcoder, switch alpha-plane compression to lossless 8d77dc2 Add support for lossless in mux: 831bd13 Make tile size a function of encoding method. 778c522 Merge "remove some variable shadowing" 817c9dc Few more HuffmanTreeToken conversions. 37a77a6 remove some variable shadowing 89c07c9 Merge "normalize example header includes" 4aff411 Merge "add example_util.[hc]" 00b29e2 normalize example header includes 061263a add example_util.[hc] c6882c4 merge all tree processing into a single VP8LProcessTree() 9c7a3cf fix VP8LHistogramNumCodes to handle the case palette_code_bits == 0 b5551d2 Merge "Added HuffmanTreeCode Struct for tree codes." 8b85d01 Added HuffmanTreeCode Struct for tree codes. 093f76d Merge "Allocate single memory in GetHuffBitLengthsAndCodes." 41d8049 Allocate single memory in GetHuffBitLengthsAndCodes. 1b04f6d Correct size in VP8L header. 2924a5a Makefile.vc: split object lists based on directory c8f2416 Merge "add assert(tokens)" 4323994 add assert(tokens) 9f54745 Catch an error in DecodeImageData(). ac8e5e4 minor typo and style fix 9f566d1 clean-up around Huffman-encode c579a71 Introduce CHUNK_SIZE_BYTES in muxi.h. 14757f8 Make sure huffman trees always have valid symbols 4105061 makefile.unix: add support for building vwebp 48b3772 Merge "fixed signed/unsigned comparison warning" 57f696d Merge "EncodeImageInternal: fix potential leak" d972cdf EncodeImageInternal: fix potential leak 5cd12c3 fixed signed/unsigned comparison warning cdca30d Merge "cosmetics: shorten long line" e025fb5 cosmetics: shorten long line 22671ed Merge "enc/vp8l: fix double free on error" e1b9b05 Merge "cosmetics: VP8LCreateHuffmanTree: fix indent" a8e725f enc/vp8l: fix double free on error 27541fb cosmetics: VP8LCreateHuffmanTree: fix indent 1d38b25 cwebp/windows: use MAKE_REFGUID where appropriate 817ef6e Merge "cwebp: fix WIC/Microsoft SDK compatibility issue" 902d3e3 cwebp: fix WIC/Microsoft SDK compatibility issue 89d803c Merge "Fix a crash due to wrong pointer-integer arithmetic." cb1bd74 Merge "Fix a crash in lossless decoder." de2fe20 Merge "Some cleanup in VP8LCreateHuffmanTree() (and related functions CompareHuffmanTrees() and SetBitDepths()): - Move 'tree_size' initialization and malloc for 'tree + tree_pool' outside the loop. - Some renames/tweaks for readability." ce69177 Fix a crash due to wrong pointer-integer arithmetic. e40a368 Fix a crash in lossless decoder. 3927ff3 remove unneeded error condition for WebPMuxNumNamedElements() 2c140e1 Some cleanup in VP8LCreateHuffmanTree() (and related functions CompareHuffmanTrees() and SetBitDepths()): - Move 'tree_size' initialization and malloc for 'tree + tree_pool' outside the loop. - Some renames/tweaks for readability. 861a5b7 add support for animation eb5c16c Merge "Set correct encode size in encoder's stats." 4abe04a fix the return value and handle missing input file case. 2fafb85 Set correct encode size in encoder's stats. e7167a2 Provide one entry point for backward references. c4ccab6 Print relevant lossless encoding stats in cwebp. e3302cf GetHuffBitLengthsAndCodes: reduce level of indirection b5f2a9e enc/vp8l: fix uninitialized variable warning 7885f8b makefile.unix: add lossless encoder files 1261a4c Merge "cosmetics" 3926b5b Merge "dsp/cpu.c: Android: fix crash on non-neon arm builds" 834f937 dsp/cpu.c: Android: fix crash on non-neon arm builds 126e160 cosmetics e38602d Merge branch 'lossless_encoder' e8d3d6a split StoreHuffmanCode() into smaller functions d0d8899 more consolidation: introduce VP8LHistogramSet 1a210ef big code clean-up and refactoring and optimization 41b5c8f Some cosmetics in histogram.c ada6ff7 Approximate FastLog between value range [256, 8192] ec123ca Forgot to update out_bit_costs to symbol_bit_costs at one instance. cf33ccd Evaluate output cluster's bit_costs once in HistogramRefine. 781c01f Simple Huffman code changes. a2849bc Lossless decoder: remove an unneeded param in ReadHuffmanCodeLengths(). b39e748 Reducing emerging palette size from 11 to 9 bits. bfc73db Move GetHistImageSymbols to histogram.c 889a578 Improve predict vs no-predict heuristic. 01f5066 code-moving and clean-up 31035f3 reduce memory usage by allocating only one histo fbb501b Restrict histo_bits to ensure histo_image size is under 32MB 8415ddf further simplification for the meta-Huffman coding e491729 A quick pass of cleanup in backward reference code 83332b3 Make transform bits a function of encode method (-m). 72920ca introduce -lossless option, protected by USE_LOSSLESS_ENCODER c6ac4df Run TraceBackwards for higher qualities. 412222c Make histo_bits and transform_bits function of quality. 149b509 Update lossless encoder strategy: 0e6fa06 cache_bits passed to EncodeImageInternal() e38b40a Factorize code for clearing HtreeGroup. 6f4a16e Removing the indirection of meta-huffman tables. 3d33ecd Some renaming/comments related to palette in lossless encoder. 4d02d58 Lossless encoder: correction in Palette storage 4a63623 fix a memleak in EncodeImageInternal() 0993a61 Full and final fix for prediction transform afd2102 Fix cross-color transform in lossless encoder b96d874 Need to write a '0' bit at the end of transforms. 54dad7e Color cache size should be counted as 0 when cache bits = 0 4f0c5ca Fix prediction transform in lossless encoder. 36dabda Fix memory leak in method EncodeImageInternal for histogram_image. 352a4f4 Get rid of PackLiteralBitLengths() d673b6b Change the predictor function to pass left pixel b2f9946 Fix CopyTileWithPrediction() 84547f5 Add EncodeImageInternal() method. 6b38378 Guard the lossless encoder (in flux) under a flag 09f7532 Fix few nits (const qualifiers) 648be39 Added implementation for various lossless functions 32714ce Add VP8L prefix to backward ref & histogram methods. fcba7be Fixed header file tag (WEBP_UTILS_HUFFMAN_ENCODE_H_) bc70374 Add backward_ref, histogram & huffman encode modules from lossless. fdccaad Fixing nits 227110c libwebp interface changes for lossless encoding. 50679ac minor style fixes b38dfcc remove unneeded reference to NUM_LITERAL_CODES 8979675 harmonize header description c04eb7b tcoder.c: define NOT_HAVE_LOG2 for MSVC builds 9a214fa Merge "VP8[L]GetInfo: check input pointers" 5c5be8b VP8[L]GetInfo: check input pointers 0c188fe Merge changes I431acdfe,I713659b7 b3515c6 mux: drop 'chunk' from ChunkInfo member names aea7923 muxi.h: remove some unused defines 0142249 update NEWS file for next release 29e3f7e Merge "dec: remove deprecated WebPINew()" 4718e44 Merge "muxedit: a few more size_t changes" 82654f9 Merge "muxedit: remove a few redundant NULL checks" 02f27fb dec: remove deprecated WebPINew() ccddb3f muxedit: remove a few redundant NULL checks a6cdf71 muxedit: a few more size_t changes a384689 Merge "mux: remove unused LIST_ID" 11ae46a alpha.c: quiet some size_t -> int conversion warnings dee4669 mux: remove unused LIST_ID 03f1f49 mux: add version checked entry points 6a0abda Merge "doc: tile/alpha corrections" c8139fb Merge "few cosmetics" 6833873 Merge "lossless: remove some size_t -> int conversions" 5249e94 doc: tile/alpha corrections d96e722 huffman: quiet int64 -> int conversion warning 532020f lossless: remove some size_t -> int conversions 23be6ed few cosmetics 1349eda Merge "configure: AC_ARG_* use AS_HELP_STRING" bfbcc60 configure: AC_ARG_* use AS_HELP_STRING 1427ca8 Merge "Makefile.am: header file maintenance" 087332e Merge "remove unused parameter 'round' from CalcProba()" 9630e16 remove unused parameter 'round' from CalcProba() 92092ea Merge "bit_reader.h: correct include" a87fc3f Merge "mux: ensure # images = # tiles" 53af99b Merge "mux: use size_t consistently" 39a57da Makefile.am: header file maintenance 1bd0bd0 bit_reader.h: correct include 326a3c6 mux: ensure # images = # tiles 95667b8 mux: use size_t consistently 231ec1f Removing the indirection of meta-huffman tables. 15ebcba check return pointer from MuxImageGetListFromId b0d6c4a Merge "configure: remove test for zlib.h" 8cccac5 Merge "dsp/lossless: silence some build warnings" b08819a dsp/lossless: silence some build warnings 7ae2252 Android.mk: SSE2 & NEON updates 0a49e3f Merge "makefile.unix add missing header files" 2e75a9a Merge "decode.h: use size_t consistently" fa13035 configure: remove test for zlib.h d3adc81 makefile.unix add missing header files 262fe01 Merge "makefile.unix & Android.mk: cosmetics" 4cce137 Merge "enc_sse2 add missing stdlib.h include" 80256b8 enc_sse2 add missing stdlib.h include 9b3d1f3 decode.h: use size_t consistently 64083d3 Merge "Makefile.am: cosmetics" dceb8b4 Merge changes If1331d3c,I86fe3847 0e33d7b Merge "webp/decode.h: fix prototypes" fac0f12 rename BitReader to VP8LBitReader fbd82b5 types.h: centralize use of stddef.h 2154835 Makefile.am: cosmetics 1c92bd3 vp8io: use size_t for buffer size 90ead71 fix some more uint32_t -> size_t typing cbe705c webp/decode.h: fix prototypes 3f8ec1c makefile.unix & Android.mk: cosmetics 217ec7f Remove tabs in configure.ac b3d35fc Merge "Android.mk & Makefile.vc: add new files" 0df04b9 Android.mk & Makefile.vc: add new files e4f20c5 Merge "automake: replace 'silent-rules' w/AM_SILENT_RULES" 8d254a0 cosmetics 6860c2e fix some uint32_t -> size_t typing 4af1858 Fix a crash due to max symbol in a tree >= alphabet size 6f01b83 split the VP8 and VP8L decoding properly f2623db enable lossless decoder b96efd7 add dec/vp8i.h changes from experimental 19f6398 add dec/vp8l{i.h,.c} from experimental c4ae53c add utils/bit_reader.[hc] changes from experimental 514d008 add dsp/lossless.[hc] from experimental 9c67291 add utils/huffman.[hc] from experimental 337914a add utils/color_cache.[hc] from experimental b3bf8fe the read-overflow code-path wasn't reporting as an error 1db888b take colorspace into account when cropping 61c2d51 move the rescaling code into its own file and make enc/ and dec/ use it. efc2016 Make rescaler methods generic 3eacee8 Move rescaler methods out of io.c. a69b893 automake: replace 'silent-rules' w/AM_SILENT_RULES 6f7bf64 issue 111: fix little-endian problem in bit-reader ed278e2 Removed unnecessary lookup cd8c3ba fix some warnings: down-cast and possibly-uninitialized variable 0a7102b ~1% improvement of alpha compression 3bc1b14 Merge "Reformat container doc" dc17abd mux: cosmetics cb5810d Merge "WebPMuxGetImage: allow image param to be NULL" 506a4af mux: cosmetics 135e8b1 WebPMuxGetImage: allow image param to be NULL de556b6 Merge "README.mux: reword some descriptions" 0ee2aeb Makefile.vc: use batch mode rules d9acddc msvc: move {i,p}db creation to object directory 237c9aa Merge "expose WebPFree function for DLL builds" b3e4054 silence msvc debug build warning 45feb55 expose WebPFree function for DLL builds 11316d8 README.mux: reword some descriptions 4be52f4 factorize WebPMuxValidate 14f6b9f mux: light cleanup 5e96a5d add more param checks to WebPPictureDistortion() 8abaf82 Merge "silence some type size related warnings" 1601a39 silence some type size related warnings f3abe52 Merge "idec: simplify buffer size calculation" a9c5cd4 idec: simplify buffer size calculation 7b06bd7 Merge "configure/automake: add silent-rules option" e9a7d14 Reformat container doc d4e5c7f configure/automake: add silent-rules option 5081db7 configure/automake: no -version-info for convenience libs 85b6ff6 Merge "idec: fix WebPIUpdate failure" 7bb6a9c idec: fix internal state corruption 89cd1bb idec: fix WebPIUpdate failure 01b6380 4-5% faster decoding, optimized byte loads in arithmetic decoder. 631117e Merge "cosmetics & warnings" a0b2736 cosmetics & warnings f73947f use 32bit for storing dequant coeffs, instead of 16b. b960030 Merge "store prediction mode array as uint8_t[16], not int[16]." 7b67881 store prediction mode array as uint8_t[16], not int[16]. cab8d4d Merge "NEON TransformOne" ba503fd NEON TransformOne 9f740e3 Merge "gcc warning fix: remove the 'const' qualifier." f76d358 gcc warning fix: remove the 'const' qualifier. e78478d Merge "webpmux: make more use of WebPData" f85bba3 Merge "manpages: add BUGS section" 48a43bb Merge "makefile.unix: variable cosmetics" c274dc9 makefile.unix: variable cosmetics 1f7b859 re-organize the error-handling in the main loop a bit 1336fa7 Only recompute level_cost_[] when needed 771ee44 manpages: add BUGS section 0f7820e webpmux: make more use of WebPData 974aaff examples: logging updates 6c14aad Merge "better token buffer code" f405425 better token buffer code 18d959f Merge "mux: add WebPData type" eec4b87 mux: add WebPData type 0de3096 use 16bit counters for recording proba counts 7f23678 fix for LevelCost + little speed-up 7107d54 further speed-up/cleanup of RecordCoeffs() and GetResidualCost() fd22104 Introduce Token buffer (unused for now) 5fa148f Merge "speed-up GetResidualCost()" 28a9d9b speed-up GetResidualCost() 11e7dad Merge "misc cosmetics" 378086b misc cosmetics d61479f add -print_psnr and -print_ssim options to cwebp. 2e3e8b2 add a WebPCleanupTransparentArea() method 552c121 Merge "mux: plug some memory leaks on error" a2a81f7 Merge "fix Mach-O shared library build" b3482c4 Merge "fix gcc-4.0 apple 32-bit build" e4e3ec1 fix gcc-4.0 apple 32-bit build b0d2fec mux: plug some memory leaks on error f0d2c7a pass of cosmetics b309a6f fix Mach-O shared library build 241ddd3 doc: delete mux container pdf 8b1ba27 doc: update VP8 decode guide link 7e4371c WebPMuxCreate: fix unchecked malloc eb42558 Merge "have makefile.unix clean up src/webp/*~ too" a85c363 Merge "correct EncodeAlpha documentation" a33842f Merge "Update webp container spec with alpha filter options." 8d6490d Incremental support for some of the mux APIs. b8375ab have makefile.unix clean up src/webp/*~ too b5855fc correct EncodeAlpha documentation dba37fe Update webp container spec with alpha filter options. 2e74ec8 fix compile under MINGW 716d1d7 fix suboptimal MAX_LEN cut-off limit 57cab7b Harmonize the alpha-filter predictions at boundary 3a98953 Merge "Fix bug for Alpha in RGBA_4444 color-mode." 8ca2076 Introduce a 'fast' alpha mode 221a06b Fix bug for Alpha in RGBA_4444 color-mode. ad1e163 cosmetics: normalize copyright headers c77424d cosmetics: light include cleanup 9d0e17c fix msvc build breakage after 252028a 7c4c177 Some readability fixes for mux library d8a47e6 Merge "Add predictive filtering option for Alpha." 252028a Add predictive filtering option for Alpha. 9b69be1 Merge "Simplify mux library code" a056170 Simplify mux library code 992187a improve log2 test e852f83 update Android.mk file list a90cb2b reduce number of copies and mallocs in alpha plane enc/dec b1662b0 fix some more type conversion warnings w/MSVC 223d8c6 fix some uint64_t -> int conversion warnings with MSC c1a0437 Merge "simplify checks for enabling SSE2 code" f06817a simplify checks for enabling SSE2 code 948d4fe silence a msvc build warning 9117954 vwebp: msvc build tweaks 7937b40 simple WebP viewer, based on OpenGL 6aac1df add a bunch of missing 'extern "C"' 421eb99 Merge "Remove assigned-but-not-used variable "br"" 91e27f4 better fitting names for upsampling functions a5d7ed5 Remove assigned-but-not-used variable "br" f62d2c9 remove unused 'has_alpha' from VP8GetInfo() signature 08e8658 trap alpha-decoding error b361eca add cut-off to arith coder probability update. 8666a93 Some bug-fixes for images with alpha. 273a12a fix off-by-1 diff in case cropping and simple filtering 2f741d1 webpmux: ReadImage: fix ptr free in error case 721f3f4 fix alpha decode 60942c8 fix the has_alpha_ order 30971c9 Implement progress report (and user abort) eda520a cosmetics after 9523f2a 38bd5bb Merge "Better alpha support in webpmux binary" ccbaebf Merge "Updated the includes to relative paths." d71fbdc fix small typo in error message array cdf97aa Better alpha support in webpmux binary 885f25b Updated the includes to relative paths. a0ec9aa Update WebP encoder (cwebp) to support Alpha. 667b769 Fixed the include for types.h within mux.h 9523f2a Add Alpha Encode support from WebPEncode. 16612dd Merge "Add Alpha Decode support from WebPDecode." d117a94 Add Alpha Decode support from WebPDecode. 6722873 cosmetics after e1947a9 e1947a9 Add Alpha encode/decode code. afc4c5d simplify code by introducing a CopyPlane() helper func 113b312 Merge "MUX API Updates" c398f59 MUX API Updates 5acf04e remove orphan source file 059f03e Merge "dec: validate colorspace before using as array index" 70a0398 Merge "factorize some code" 9b243b3 factorize some code 372e2b4 Correct a bug in ReadPNG() with GRAY_ALPHA images 469d6eb Merge "Makefile.am: remove redundant noinst_HEADERS" 9fe3372 dec: validate colorspace before using as array index 8962030 remove orphan source file ced3e3f Makefile.am: remove redundant noinst_HEADERS 964387e use WEBP_INLINE for inline function declarations 90880a1 Merge "manpages: break long lines" b591089 Merge "manpages: minor formatting updates" 4c451e4 Merge "Rectify the Chunk parsing logic." 04e84cf examples: slight cleanup 099717c manpages: break long lines 1daf39b manpages: minor formatting updates abd030b fix missing "(void)" in function signature f6a7d75 remove useless test f07b213 Rectify the Chunk parsing logic. b8634f7 webpmux: fix lib link order 42c2e68 Fix missing coma (on uncompiled code) d8329d4 Android.mk: add missing source files 13a54df Merge "More aggressive copy-edit; add TODO; validate HTML5" 868b96a More aggressive copy-edit; add TODO; validate HTML5 767afea configure: check for a symbol contained in libpng 408b891 Merge "Linewrap at 72 cols. Casual copy-edit." 3ae318c Merge "Restore (most) emphasis; add emphasis to normative RFC 2119 terms (MUST, etc.)" 918eb2d Merge "Basic container doc source clean-up; fix lists and pseudocode blocks." 03bec9e Linewrap at 72 cols. Casual copy-edit. 2678d81 Restore (most) emphasis; add emphasis to normative RFC 2119 terms (MUST, etc.) 428674d Basic container doc source clean-up; fix lists and pseudocode blocks. 6a77d92 Merge "Makefile.vc: cosmetics" 28c38e8 Merge "Makefile.vc: condense directory creation rules" 55be2cf Initial import of container spec document, from pdftotext transform. a82a788 Makefile.vc: cosmetics c8f41ce Makefile.vc: condense directory creation rules 2b877cd Some fixes to Makefile.vc to support the src\mux directory. 3eb969b Merge "Add Makefile.vc for Mux library & binary." e78e971 Add Makefile.vc for Mux library & binary. 6aedde5 Add manual for WebPMux tool. 8a360d0 Merge "Added WebPMux Binary." a4f32ca Added WebPMux Binary. f3bf4c7 Added Mux Container Spec & README for MUX-API. 9f761cf Changed function signature for WebPMuxCreate 5f31b5e Merge "Add Mux library for manipulating WebP container." 2315785 Add Mux library for manipulating WebP container. 7e198ab update ChangeLog (tag: v0.1.3) dfc9c1e Harmonize the dates 28ad70c Fix PNG decoding bug 846e93c Update AUTHORS & add .mailmap 563e52d cosmetics after '76036f5 Refactor decoder library' 76036f5 Refactor decoder library 377ef43 configure.ac: update AC_INIT params 7a8d876 use a user-visible MACRO for max width/height. d4e9f55 NEON decode support in WebP 0ee683b update libtool version-info fdbe02c windows: match _cond_destroy logic w/return variable name 206b686 README: correct advanced decode api pseudo-code 6a32a0f make VP8BitReader a typedef, for better re-use b112e83 create a libwebputils under src/utils ee697d9 harmonize the include guards and #endif comments a1ec07a Fixing compiler error in non x86 arch. dcfa509 Fixed recursive inclusion of bit_writer.h and vp8enci.h. e06ac08 create a separate libwebpdsp under src/dsp ebeb412 use unsigned int for bitfields 341cc56 make kNewRange a static array 227a91e README: minor wording update 05bd8e6 add man pages to dist 812dfa1 bump up versions in preparations for 0.1.3 a5b78c8 wrap alpha-related options under WEBP_EXPERIMENTAL_FEATURES flag 34dc790 regen ChangeLog for 0.1.3-rc2 7c43663 Silence some (more) Visual Studio warnings. 60306e8 add top-level gitattributes 2aa6b80 Slience some Visual Studio warnings. 4cbbb29 Merge "bump up version for next freeze" a329167 bump up version for next freeze c7e86ab cosmetics: fix comment line lengths c9e037a makefile.unix: add simple dist target 87d58ce makefile.unix: rule maintenance d477de7 mend fac15ec Update NEWS & README for next release V0.1.3 6215595 Merge "add a -partition_limit option to limit the number of bits used by intra4x4" 3814b76 Merge "reorganize chunk-parsing code" 900286e add a -partition_limit option to limit the number of bits used by intra4x4 cd12b4b add the missing cost for I4/I16 mode selection dfcc213 reorganize chunk-parsing code 3cf2030 initialize pointers to function within VP8DspInit() d21b479 Merge "windows: add decode threading support" 473ae95 fix hang on thread creation failure fccca42 windows: add decode threading support a31f843 Use the exact PNG_INCLUDES/PNG_LIBS when testing for -lpng ad9b45f Merge "Makefile.vc: rule maintenance" 565a2ca Makefile.vc: rule maintenance 2d0da68 makefile.unix: disable Wvla by default fc7815d multi-thread decoding: ~25-30% faster acd8ba4 io->teardown() was not always called upon error c85527b Merge "Makefile.vc: add DLL configs" e1e9be3 cosmetics: spelling/grammar in README and lib headers b4d0ef8 Makefile.vc: add DLL configs 998754a remove unused nb_i4_ and nb_i16_ fields. 9f01ce3 rename WebPDecBuffer::memory -> private_memory fb5d659 fix an overflow bug in LUT calculation d646d5c swig: add WebPDecodeARGB 78aeed4 add missing WebPDecodeARGBInto() and switch ARGB4444 to RGBA4444 as was intended cd7c529 explicitly mark library functions as extern 19db59f add support for RGB565, ARGB4444 and ARGB colorspace (decoder) c915fb2 encoder speed-up: hardcode special level values c558bda Rename and improve the API to retrieve decoded area bf599d7 Merge "makefile.unix: disable -Wvla by default" c9ea03d SSE2 version of strong filtering 993af3e makefile.unix: disable -Wvla by default 3827e1b Merge "examples: (windows/WIC) add alpha support" e291fae SSE2 functions for the fancy upsampler. a06bbe2 add WebPISetIOHooks() to set some custom hooks on the incremental decoder object. 7643a6f Merge "makefile.unix: use uname to detect OSX environment" 5142a0b export alpha channel (if present) when dumping to PGM format 14d5731 makefile.unix: use uname to detect OSX environment 0805706 examples: quiet warnings 3cfe088 examples: (windows/WIC) add alpha support 13ed94b add compile warning for variable-length-array 5a18eb1 Merge "add Advanced Decoding Interface" 5c4f27f add missing \n f4c4e41 80 cols fix d260310 add Advanced Decoding Interface bd2f65f sse2 version of the complex filter 96ed9ce perform two idct transforms at a time when possible 01af7b6 use aligned stored 0e1d1fd Merge "Makefile.vc: add experimental target" 2a1292a Makefile.vc: add experimental target 23bf351 Enable decode SSE2 for Visual Studio 131a4b7 dec/dsp_sse2: fix visual studio compile 00d9d68 swig: file reorganization 7fc7e0d Merge "swig/java: basic encode support" 3be57b1 fix MSVC compile for WEBP_EXPERIMENTAL_FEATURES 40a7e34 dec/dsp: disable sse2 for Visual Studio builds e4d540c add SSE2 code for transform 54f2170 swig/java: basic encode support c5d4584 call function pointers instead of C-version ea43f04 Merge "configure: mingw32 targets: test for WIC support" a11009d SSE2 version of simple in-loop filtering 42548da shave one unneeded filter-cache line 31f9dc6 configure: mingw32 targets: test for WIC support 1955969 Merge "split expression in two." 415dbe4 split expression in two. e29072a configure: test for zlib only w/--enable-experimental b2b0090 Simplify Visual Studio ifdefs ca7a2fd Add error reporting from encoding failures. 6c9405d Merge "Makefile.vc: require CFG with clean target" 0424ecd Makefile.vc: require CFG with clean target 003417c Enable SSE2 for Visual Studio builds af10db4 little speed up for VP8BitUpdate() e71418f more MSVC files to ignore 46d9036 cosmetics edf59ab typo fix 72229f5 Add support for x64 and SSE2 builds under Windows. 92e5c6e VP8GetInfo() + WebPResetDecParams() 416b7a6 raise the fixed-point precision for the rescaler aa87e4e fix alignment eb66670 disable WEBP_EXPERIMENTAL_FEATURES c5ae7f6 typo fix: USE_ => WEBP_ d041efa swig: add libwebp.jar/libwebp_java_wrap.c f6fb387 add swig interface e927390 align buffer for double too 842c009 fix -strong option d0a7038 Merge "cosmetics" fc0a02e fix the dichotomy loop 38369c0 cosmetics 8dfc4c6 factorize and unify GetAlpha() between the C and SSE2 version 6d0e66c prepare experimentation with yuv444 / 422 79cc49f add a --enable-experimental option to './configure' d757523 sse2 version of CollectHistogram() c1c728d add an extra #ifdef WEBP_EXPERIMENTAL_FEATURES to avoid 'unused variable' warning 60c61d2 always call VP*EncDeleteAlpha() unconditionnally, for simplicity 0f8c638 simply don't call WriteExtensions() if WEBP_EXPERIMENTAL_FEATURES is not defined 47c661d rename swap -> swap_rb 10d55bb move chunk[] declaration out of the for() loop 517cec2 fix indentation f7d9e26 fix merge problems 8fd42b3 add a stride 'a_stride' for the alpha plane b8dcbf2 fix alpha-plane copy and crop methods cdef89d fix some 'unused variable' warning fb29c26 SSE2 version of the fwd transform and the squared sum metric 2ab4b72 EXPERIMENTAL: add support for alpha channel cfbf88a add SSE2 functions. ~2x faster encoding on average. e7ff3f9 merge two ITransforms together when applicable and change the TTransform to return the sum directly. ca55413 fix WebPIDecGetRGB() to accept any RGB(A) mode, not just MODE_RGB 8aa50ef fix some 'man' typos d3f3bdd update ChangeLog (tag: v0.1.2) d7e9a69 update contributor list 261abb8 add a 'superclean' section 276ae82 Remove files not mean to be in git, and update .gitignore 2486845 build: prepare libwebp.pc 14ceb6e add "-version" description to man pages b247a3b Create the m4 directory, and also place .gitignore in there for libtool. cdd734c Resolve automake warnings c5fa726 build: add pkgconfig files b20aaca build: just use autoreconf, avoid calling tools manually 4b0b0d6 cwebp: use modern functions efbc6c4 update Android.mk 7777570 better version of ChangeLog fa70d2b update version number in the DOC f8db5d5 more C89-fixes 0de013b fix typos 650ffa3 add version getters for decoder and encoder be4867d doc for incremental decoding 56732a1 add idec.obj in MSVC makefile 208afb5 add c++ guards 8bf76fe add incremental decoding 1f28832 'inline' isn't defined in strict ansi c89 8b77c63 move the quantization function to dsp.c b2c3575 add a 'last_y' field to WebPDecParams 2654c3d correctly pass along the exact same status returned from ParsePartitions 4704146 add missing precision in the man 6d978a6 add error messages 6463e6a add some install instructions, and fix intel-mac flags 05fb7bf Merge ".gitignore: initial version" c33f019 .gitignore: initial version e532b9a Makefile: allow out of tree builds 4c0da7a enable sparse dc/ac transforms 07dbb8d clarify the return logic 5c69e1b fix bigger-by-1 array 7c5267e fix a (harmless) typo: non_zero_ -> non_zero_ac_ bc75213 fix missing free() af3e2aa remove trailing spaces 13e50da make the bitreader preload at least 8bits, instead of post-load them (this makes initialization easier and will be helpful for incremental decoding). Modify ParsePartitions() to accommodate for truncated input. f4888f7 emit 9 - nb_bits trailing zeros instead of 8 3db6525 separate block-parsing into a visible VP8DecodeMB() a871de0 add missing extern "C" b3ce8c5 remove a gcc warning about type pun by using a proper union'd type e186371 update after addition of webpi.h 3e856e2 Extract some useful functions around decoding buffer WebPDecParams. d5bc05a make the filtering process match libvpx and ffvp8 dd60138 add man pages for cwebp(1) and dwebp(1) c4fa364 fix header 5b70b37 * add an option to bypass_filtering in VP8Io. b97a400 simplify QuantizeBlock code a bit 84b58eb add more checks around picture allocation b65a3e1 remove absolute_delta_ field and syntax code 0744e84 Dont' open output file until we're sure the input file is valid d5bd54c fix typo and buggy line f7a9549 Add a simple top-level makefile.unix for quick & easy build. 5f36b94 update the doc for the -f option f61d14a a WebP encoder converts PNG & JPEG to WebP 81c9662 oops: forgotten call to Initialize() + move the error message to a more useful place 87ffa00 typo: fix a missing 'R', was confusing. b04b857 * add decoding measurement using stopwatch.h (use -v option) * support PNG output through WIC on Win32 746a482 * make (*put)() hook return a bool for abort request. * add an enum for VP8Status() to make things clearer 73c973e * strengthen riff/chunk size checks * don't consider odd-sized chunks being an error 1dc4611 add support for PNG output (default) regularize include guards 860641d fix a typo: sizeof(kYModeProbaInter0) => sizeof(kUVModeProbaInter0) 3254fc5 fix some petty constness fix the ./configure file too 504d339 fix eof_ mis-initialization 2bc0778 leftover Makefile.* from previous commit d2cf04e move Makefile.am one level below, to src/dec fix typos here and there dwebp is now an installed program ade92de typo: vp8.h -> decode_vp8.h d724124 forgot to declare types.h to be installed 6421a7a move the decoder sourcetree to a sub-location src/dec to make room for future libs sources a9b3eab correct layout name is IMC4. 2330522 handle corner case of zero-dimensions 280c365 make VP8Init() handle short buffers (< 2 bytes) correctly b1c9e8b handle error cases more robustly 0e94935 Merge "table-less version of clip_8b()" 1e0a2d2 table-less version of clip_8b() e12109e dwebp: change -yuv option to -raw change the layout to IMC2 d72180a speed-up fancy upscaler 9145f3b reset eof_ at construction time a7ee055 simplify the logic of GetCoeffs() f67b593 lot of cosmetics ea27d7c fix endian problem on PowerPC beb0a1b fix signature of VP8StoreBlock b128c5e Merge "fancy chroma upscaling" 6a37a2a fancy chroma upscaling ff565ed fix two numeric typos 5a936a0 use uintptr_t for casting pointers to ints e14a030 for cross_compiling=yes to prevent executing any binary 83b545e add vc9+ makefile 296f691 fix output loop for small height cbfbb5c convert to plain-C f09f96e Fix declaration after statement warning 5981ee5 Fix UV plane ac/dc quantizer transposition c8d15ef convert to ANSI-C c3f41cb Initial commit libwebp-0.4.0/aclocal.m40000644000014400001440000011627512255206712011725 0ustar # generated automatically by aclocal 1.11.3 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, # Inc. # This file 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. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, [m4_warning([this file was generated for autoconf 2.68. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software # Foundation, Inc. # # This file 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. # serial 1 # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011 Free Software Foundation, Inc. # # This file 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. # serial 1 # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) ]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file 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. # serial 1 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file 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. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, # 2010, 2011 Free Software Foundation, Inc. # # This file 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. # serial 12 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file 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. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file 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. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, # Inc. # # This file 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. # serial 1 # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file 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. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file 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. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file 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. # serial 6 # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file 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. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, # Inc. # # This file 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. # serial 1 # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software # Foundation, Inc. # # This file 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. # serial 5 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file 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. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2009, 2011 Free Software Foundation, Inc. # # This file 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. # serial 2 # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # (`yes' being less verbose, `no' or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [ --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0')]) case $enable_silent_rules in yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few `make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using `$V' instead of `$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file 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. # serial 1 # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file 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. # serial 3 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file 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. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_pthread.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) libwebp-0.4.0/config.guess0000755000014400001440000012743212255206714012404 0ustar #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file 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 2 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 . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libwebp-0.4.0/config.h.in0000644000014400001440000000562312255206713012103 0ustar /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_GLUT_GLUT_H /* Define to 1 if you have the header file. */ #undef HAVE_GL_GLUT_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENGL_GLUT_H /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT /* Define to 1 if you have the header file. */ #undef HAVE_SHLWAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_WINCODEC_H /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Enable experimental code */ #undef WEBP_EXPERIMENTAL_FEATURES /* Set to 1 if GIF library is installed */ #undef WEBP_HAVE_GIF /* Set to 1 if OpenGL is supported */ #undef WEBP_HAVE_GL /* Set to 1 if JPEG library is installed */ #undef WEBP_HAVE_JPEG /* Set to 1 if PNG library is installed */ #undef WEBP_HAVE_PNG /* Set to 1 if TIFF library is installed */ #undef WEBP_HAVE_TIFF /* Undefine this to disable thread support. */ #undef WEBP_USE_THREAD libwebp-0.4.0/README0000644000014400001440000005532412255002107010732 0ustar __ __ ____ ____ ____ / \\/ \/ _ \/ _ )/ _ \ \ / __/ _ \ __/ \__\__/\____/\_____/__/ ____ ___ / _/ / \ \ / _ \/ _/ / \_/ / / \ \ __/ \__ \____/____/\_____/_____/____/v0.4.0 Description: ============ WebP codec: library to encode and decode images in WebP format. This package contains the library that can be used in other programs to add WebP support, as well as the command line tools 'cwebp' and 'dwebp'. See http://developers.google.com/speed/webp Latest sources are available from http://www.webmproject.org/code/ It is released under the same license as the WebM project. See http://www.webmproject.org/license/software/ or the file "COPYING" file for details. An additional intellectual property rights grant can be found in the file PATENTS. Building: ========= Windows build: -------------- By running: nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output the directory output\release-static\(x64|x86)\bin will contain the tools cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will contain the libwebp static library. The target architecture (x86/x64) is detected by Makefile.vc from the Visual Studio compiler (cl.exe) available in the system path. Unix build using makefile.unix: ------------------------------- On platforms with GNU tools installed (gcc and make), running make -f makefile.unix will build the binaries examples/cwebp and examples/dwebp, along with the static library src/libwebp.a. No system-wide installation is supplied, as this is a simple alternative to the full installation system based on the autoconf tools (see below). Please refer to makefile.unix for additional details and customizations. Using autoconf tools: --------------------- When building from git sources, you will need to run autogen.sh to generate the configure script. ./configure make make install should be all you need to have the following files /usr/local/include/webp/decode.h /usr/local/include/webp/encode.h /usr/local/include/webp/types.h /usr/local/lib/libwebp.* /usr/local/bin/cwebp /usr/local/bin/dwebp installed. Note: A decode-only library, libwebpdecoder, is available using the '--enable-libwebpdecoder' flag. The encode library is built separately and can be installed independently using a minor modification in the corresponding Makefile.am configure files (see comments there). See './configure --help' for more options. SWIG bindings: -------------- To generate language bindings from swig/libwebp.swig at least swig-1.3 (http://www.swig.org) is required. Currently the following functions are mapped: Decode: WebPGetDecoderVersion WebPGetInfo WebPDecodeRGBA WebPDecodeARGB WebPDecodeBGRA WebPDecodeBGR WebPDecodeRGB Encode: WebPGetEncoderVersion WebPEncodeRGBA WebPEncodeBGRA WebPEncodeRGB WebPEncodeBGR WebPEncodeLosslessRGBA WebPEncodeLosslessBGRA WebPEncodeLosslessRGB WebPEncodeLosslessBGR See swig/README for more detailed build instructions. Java bindings: To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent) is necessary for enum support. The output is intended to be a shared object / DLL that can be loaded via System.loadLibrary("webp_jni"). Python bindings: To build the swig-generated Python extension code at least Python 2.6 is required. Python < 2.6 may build with some minor changes to libwebp.swig or the generated code, but is untested. Encoding tool: ============== The examples/ directory contains tools for encoding (cwebp) and decoding (dwebp) images. The easiest use should look like: cwebp input.png -q 80 -o output.webp which will convert the input file to a WebP file using a quality factor of 80 on a 0->100 scale (0 being the lowest quality, 100 being the best. Default value is 75). You might want to try the -lossless flag too, which will compress the source (in RGBA format) without any loss. The -q quality parameter will in this case control the amount of processing time spent trying to make the output file as small as possible. A longer list of options is available using the -longhelp command line flag: > cwebp -longhelp Usage: cwebp [-preset <...>] [options] in_file [-o out_file] If input size (-s) for an image is not specified, it is assumed to be a PNG, JPEG or TIFF file. options: -h / -help ............ short help -H / -longhelp ........ long help -q ............. quality factor (0:small..100:big) -alpha_q ......... Transparency-compression quality (0..100). -preset ....... Preset setting, one of: default, photo, picture, drawing, icon, text -preset must come first, as it overwrites other parameters. -m ............... compression method (0=fast, 6=slowest) -segments ........ number of segments to use (1..4) -size ............ Target size (in bytes) -psnr .......... Target PSNR (in dB. typically: 42) -s ......... Input size (width x height) for YUV -sns ............. Spatial Noise Shaping (0:off, 100:max) -f ............... filter strength (0=off..100) -sharpness ....... filter sharpness (0:most .. 7:least sharp) -strong ................ use strong filter instead of simple (default). -nostrong .............. use simple filter instead of strong. -partition_limit . limit quality to fit the 512k limit on the first partition (0=no degradation ... 100=full) -pass ............ analysis pass number (1..10) -crop .. crop picture with the given rectangle -resize ........ resize picture (after any cropping) -mt .................... use multi-threading if available -low_memory ............ reduce memory usage (slower encoding) -map ............. print map of extra info. -print_psnr ............ prints averaged PSNR distortion. -print_ssim ............ prints averaged SSIM distortion. -print_lsim ............ prints local-similarity distortion. -d .......... dump the compressed output (PGM file). -alpha_method .... Transparency-compression method (0..1) -alpha_filter . predictive filtering for alpha plane. One of: none, fast (default) or best. -alpha_cleanup ......... Clean RGB values in transparent area. -blend_alpha ..... Blend colors against background color expressed as RGB values written in hexadecimal, e.g. 0xc0e0d0 for red=0xc0 green=0xe0 and blue=0xd0. -noalpha ............... discard any transparency information. -lossless .............. Encode image losslessly. -hint ......... Specify image characteristics hint. One of: photo, picture or graph -metadata ..... comma separated list of metadata to copy from the input to the output if present. Valid values: all, none (default), exif, icc, xmp -short ................. condense printed message -quiet ................. don't print anything. -version ............... print version number and exit. -noasm ................. disable all assembly optimizations. -v ..................... verbose, e.g. print encoding/decoding times -progress .............. report encoding progress Experimental Options: -jpeg_like ............. Roughly match expected JPEG size. -af .................... auto-adjust filter strength. -pre ............. pre-processing filter The main options you might want to try in order to further tune the visual quality are: -preset -sns -f -m Namely: * 'preset' will set up a default encoding configuration targeting a particular type of input. It should appear first in the list of options, so that subsequent options can take effect on top of this preset. Default value is 'default'. * 'sns' will progressively turn on (when going from 0 to 100) some additional visual optimizations (like: segmentation map re-enforcement). This option will balance the bit allocation differently. It tries to take bits from the "easy" parts of the picture and use them in the "difficult" ones instead. Usually, raising the sns value (at fixed -q value) leads to larger files, but with better quality. Typical value is around '75'. * 'f' option directly links to the filtering strength used by the codec's in-loop processing. The higher the value, the smoother the highly-compressed area will look. This is particularly useful when aiming at very small files. Typical values are around 20-30. Note that using the option -strong/-nostrong will change the type of filtering. Use "-f 0" to turn filtering off. * 'm' controls the trade-off between encoding speed and quality. Default is 4. You can try -m 5 or -m 6 to explore more (time-consuming) encoding possibilities. A lower value will result in faster encoding at the expense of quality. Decoding tool: ============== There is a decoding sample in examples/dwebp.c which will take a .webp file and decode it to a PNG image file (amongst other formats). This is simply to demonstrate the use of the API. You can verify the file test.webp decodes to exactly the same as test_ref.ppm by using: cd examples ./dwebp test.webp -ppm -o test.ppm diff test.ppm test_ref.ppm The full list of options is available using -h: > dwebp -h Usage: dwebp in_file [options] [-o out_file] Decodes the WebP image file to PNG format [Default] Use following options to convert into alternate image formats: -pam ......... save the raw RGBA samples as a color PAM -ppm ......... save the raw RGB samples as a color PPM -bmp ......... save as uncompressed BMP format -tiff ........ save as uncompressed TIFF format -pgm ......... save the raw YUV samples as a grayscale PGM file with IMC4 layout -yuv ......... save the raw YUV samples in flat layout Other options are: -version .... print version number and exit. -nofancy ..... don't use the fancy YUV420 upscaler. -nofilter .... disable in-loop filtering. -nodither .... disable dithering. -dither .. dithering strength (in 0..100) -mt .......... use multi-threading -crop ... crop output with the given rectangle -scale .......... scale the output (*after* any cropping) -alpha ....... only save the alpha plane. -incremental . use incremental decoding (useful for tests) -h ....... this help message. -v ....... verbose (e.g. print encoding/decoding times) -noasm ....... disable all assembly optimizations. Visualization tool: =================== There's a little self-serve visualization tool called 'vwebp' under the examples/ directory. It uses OpenGL to open a simple drawing window and show a decoded WebP file. It's not yet integrated in the automake build system, but you can try to manually compile it using the recommendations below. Usage: vwebp in_file [options] Decodes the WebP image file and visualize it using OpenGL Options are: -version .... print version number and exit. -noicc ....... don't use the icc profile if present. -nofancy ..... don't use the fancy YUV420 upscaler. -nofilter .... disable in-loop filtering. -dither dithering strength (0..100). Default=50. -mt .......... use multi-threading. -info ........ print info. -h ....... this help message. Keyboard shortcuts: 'c' ................ toggle use of color profile. 'i' ................ overlay file information. 'q' / 'Q' / ESC .... quit. Building: --------- Prerequisites: 1) OpenGL & OpenGL Utility Toolkit (GLUT) Linux: $ sudo apt-get install freeglut3-dev mesa-common-dev Mac + XCode: - These libraries should be available in the OpenGL / GLUT frameworks. Windows: http://freeglut.sourceforge.net/index.php#download 2) (Optional) qcms (Quick Color Management System) i. Download qcms from Mozilla / Chromium: http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms ii. Build and archive the source files as libqcms.a / qcms.lib iii. Update makefile.unix / Makefile.vc a) Define WEBP_HAVE_QCMS b) Update include / library paths to reference the qcms directory. Build using makefile.unix / Makefile.vc: $ make -f makefile.unix examples/vwebp > nmake /f Makefile.vc CFG=release-static \ ../obj/x64/release-static/bin/vwebp.exe Animated GIF conversion: ======================== Animated GIF files can be converted to WebP files with animation using the gif2webp utility available under examples/. The files can then be viewed using vwebp. Usage: gif2webp [options] gif_file -o webp_file options: -h / -help ............ this help -lossy ................. Encode image using lossy compression. -mixed ................. For each frame in the image, pick lossy or lossless compression heuristically. -q ............. quality factor (0:small..100:big) -m ............... compression method (0=fast, 6=slowest) -kmin ............ Min distance between key frames -kmax ............ Max distance between key frames -f ............... filter strength (0=off..100) -metadata ..... comma separated list of metadata to copy from the input to the output if present. Valid values: all, none, icc, xmp (default) -mt .................... use multi-threading if available -version ............... print version number and exit. -v ..................... verbose. -quiet ................. don't print anything. Building: --------- With the libgif development files installed, gif2webp can be built using makefile.unix: $ make -f makefile.unix examples/gif2webp or using autoconf: $ ./configure --enable-everything $ make Encoding API: ============= The main encoding functions are available in the header src/webp/encode.h The ready-to-use ones are: size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output); size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output); size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output); They will convert raw RGB samples to a WebP data. The only control supplied is the quality factor. There are some variants for using the lossless format: size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, int stride, uint8_t** output); size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, int stride, uint8_t** output); size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output); Of course in this case, no quality factor is needed since the compression occurs without loss of the input values, at the expense of larger output sizes. Advanced encoding API: ---------------------- A more advanced API is based on the WebPConfig and WebPPicture structures. WebPConfig contains the encoding settings and is not tied to a particular picture. WebPPicture contains input data, on which some WebPConfig will be used for compression. The encoding flow looks like: -------------------------------------- BEGIN PSEUDO EXAMPLE #include // Setup a config, starting form a preset and tuning some additional // parameters WebPConfig config; if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) return 0; // version error } // ... additional tuning config.sns_strength = 90; config.filter_sharpness = 6; config_error = WebPValidateConfig(&config); // not mandatory, but useful // Setup the input data WebPPicture pic; if (!WebPPictureInit(&pic)) { return 0; // version error } pic.width = width; pic.height = height; // allocated picture of dimension width x height if (!WebPPictureAllocate(&pic)) { return 0; // memory error } // at this point, 'pic' has been initialized as a container, // and can receive the Y/U/V samples. // Alternatively, one could use ready-made import functions like // WebPPictureImportRGB(), which will take care of memory allocation. // In any case, past this point, one will have to call // WebPPictureFree(&pic) to reclaim memory. // Set up a byte-output write method. WebPMemoryWriter, for instance. WebPMemoryWriter wrt; pic.writer = MyFileWriter; pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work; // initialize 'wrt' here... // Compress! int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred! WebPPictureFree(&pic); // must be called independently of the 'ok' result. // output data should have been handled by the writer at that point. -------------------------------------- END PSEUDO EXAMPLE Decoding API: ============= This is mainly just one function to call: #include "webp/decode.h" uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height); Please have a look at the file src/webp/decode.h for the details. There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw Y'CbCr samples. One can also decode the image directly into a pre-allocated buffer. To detect a WebP file and gather the picture's dimensions, the function: int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); is supplied. No decoding is involved when using it. Incremental decoding API: ========================= In the case when data is being progressively transmitted, pictures can still be incrementally decoded using a slightly more complicated API. Decoder state is stored into an instance of the WebPIDecoder object. This object can be created with the purpose of decoding either RGB or Y'CbCr samples. For instance: WebPDecBuffer buffer; WebPInitDecBuffer(&buffer); buffer.colorspace = MODE_BGR; ... WebPIDecoder* idec = WebPINewDecoder(&buffer); As data is made progressively available, this incremental-decoder object can be used to decode the picture further. There are two (mutually exclusive) ways to pass freshly arrived data: either by appending the fresh bytes: WebPIAppend(idec, fresh_data, size_of_fresh_data); or by just mentioning the new size of the transmitted data: WebPIUpdate(idec, buffer, size_of_transmitted_buffer); Note that 'buffer' can be modified between each call to WebPIUpdate, in particular when the buffer is resized to accommodate larger data. These functions will return the decoding status: either VP8_STATUS_SUSPENDED if decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other status is an error condition. The 'idec' object must always be released (even upon an error condition) by calling: WebPDelete(idec). To retrieve partially decoded picture samples, one must use the corresponding method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable pixel row. Lastly, note that decoding can also be performed into a pre-allocated pixel buffer. This buffer must be passed when creating a WebPIDecoder, calling WebPINewRGB() or WebPINewYUVA(). Please have a look at the src/webp/decode.h header for further details. Advanced Decoding API: ====================== WebP decoding supports an advanced API which provides on-the-fly cropping and rescaling, something of great usefulness on memory-constrained environments like mobile phones. Basically, the memory usage will scale with the output's size, not the input's, when one only needs a quick preview or a zoomed in portion of an otherwise too-large picture. Some CPU can be saved too, incidentally. -------------------------------------- BEGIN PSEUDO EXAMPLE // A) Init a configuration object WebPDecoderConfig config; CHECK(WebPInitDecoderConfig(&config)); // B) optional: retrieve the bitstream's features. CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); // C) Adjust 'config' options, if needed config.options.no_fancy_upsampling = 1; config.options.use_scaling = 1; config.options.scaled_width = scaledWidth(); config.options.scaled_height = scaledHeight(); // etc. // D) Specify 'config' output options for specifying output colorspace. // Optionally the external image decode buffer can also be specified. config.output.colorspace = MODE_BGRA; // Optionally, the config.output can be pointed to an external buffer as // well for decoding the image. This externally supplied memory buffer // should be big enough to store the decoded picture. config.output.u.RGBA.rgba = (uint8_t*) memory_buffer; config.output.u.RGBA.stride = scanline_stride; config.output.u.RGBA.size = total_size_of_the_memory_buffer; config.output.is_external_memory = 1; // E) Decode the WebP image. There are two variants w.r.t decoding image. // The first one (E.1) decodes the full image and the second one (E.2) is // used to incrementally decode the image using small input buffers. // Any one of these steps can be used to decode the WebP image. // E.1) Decode full image. CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); // E.2) Decode image incrementally. WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config); CHECK(idec != NULL); while (bytes_remaining > 0) { VP8StatusCode status = WebPIAppend(idec, input, bytes_read); if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) { bytes_remaining -= bytes_read; } else { break; } } WebPIDelete(idec); // F) Decoded image is now in config.output (and config.output.u.RGBA). // It can be saved, displayed or otherwise processed. // G) Reclaim memory allocated in config's object. It's safe to call // this function even if the memory is external and wasn't allocated // by WebPDecode(). WebPFreeDecBuffer(&config.output); -------------------------------------- END PSEUDO EXAMPLE Bugs: ===== Please report all bugs to our issue tracker: http://code.google.com/p/webp/issues Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/ Discuss: ======== Email: webp-discuss@webmproject.org Web: http://groups.google.com/a/webmproject.org/group/webp-discuss libwebp-0.4.0/README.mux0000644000014400001440000001453612255002107011542 0ustar  __ __ ____ ____ ____ __ __ _ __ __ / \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\ \ / __/ _ \ __/ / / (_/ /__ \__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.2.0 Description: ============ WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and manipulation of an extended format WebP file, which can have features like color profile, metadata and animation. Reference command-line tools 'webpmux' and 'vwebp' as well as the WebP container specification 'doc/webp-container-spec.txt' are also provided in this package. WebP Mux tool: ============== The examples/ directory contains a tool (webpmux) for manipulating WebP files. The webpmux tool can be used to create an extended format WebP file and also to extract or strip relevant data from such a file. A list of options is available using the -help command line flag: > webpmux -help Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT webpmux -set SET_OPTIONS INPUT -o OUTPUT webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT] [-bgcolor BACKGROUND_COLOR] -o OUTPUT webpmux -info INPUT webpmux [-h|-help] webpmux -version GET_OPTIONS: Extract relevant data. icc Get ICC profile. exif Get EXIF metadata. xmp Get XMP metadata. frame n Get nth frame. SET_OPTIONS: Set color profile/metadata. icc file.icc Set ICC profile. exif file.exif Set EXIF metadata. xmp file.xmp Set XMP metadata. where: 'file.icc' contains the ICC profile to be set, 'file.exif' contains the EXIF metadata to be set 'file.xmp' contains the XMP metadata to be set STRIP_OPTIONS: Strip color profile/metadata. icc Strip ICC profile. exif Strip EXIF metadata. xmp Strip XMP metadata. FRAME_OPTIONS(i): Create animation. file_i +di+[xi+yi[+mi[bi]]] where: 'file_i' is the i'th animation frame (WebP format), 'di' is the pause duration before next frame. 'xi','yi' specify the image offset for this frame. 'mi' is the dispose method for this frame (0 or 1). 'bi' is the blending method for this frame (+b or -b). LOOP_COUNT: Number of times to repeat the animation. Valid range is 0 to 65535 [Default: 0 (infinite)]. BACKGROUND_COLOR: Background color of the canvas. A,R,G,B where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying the Alpha, Red, Green and Blue component values respectively [Default: 255,255,255,255]. INPUT & OUTPUT are in WebP format. Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be valid. Visualization tool: =================== The examples/ directory also contains a tool (vwebp) for viewing WebP files. It decodes the image and visualizes it using OpenGL. See the libwebp README for details on building and running this program. Mux API: ======== The Mux API contains methods for adding data to and reading data from WebP files. This API currently supports XMP/EXIF metadata, ICC profile and animation. Other features may be added in subsequent releases. Example#1 (pseudo code): Creating a WebPMux object with image data, color profile and XMP metadata. int copy_data = 0; WebPMux* mux = WebPMuxNew(); // ... (Prepare image data). WebPMuxSetImage(mux, &image, copy_data); // ... (Prepare ICC profile data). WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); // ... (Prepare XMP metadata). WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data); // Get data from mux in WebP RIFF format. WebPMuxAssemble(mux, &output_data); WebPMuxDelete(mux); // ... (Consume output_data; e.g. write output_data.bytes to file). WebPDataClear(&output_data); Example#2 (pseudo code): Get image and color profile data from a WebP file. int copy_data = 0; // ... (Read data from file). WebPMux* mux = WebPMuxCreate(&data, copy_data); WebPMuxGetFrame(mux, 1, &image); // ... (Consume image; e.g. call WebPDecode() to decode the data). WebPMuxGetChunk(mux, "ICCP", &icc_profile); // ... (Consume icc_profile). WebPMuxDelete(mux); free(data); For a detailed Mux API reference, please refer to the header file (src/webp/mux.h). Demux API: ========== The Demux API enables extraction of images and extended format data from WebP files. This API currently supports reading of XMP/EXIF metadata, ICC profile and animated images. Other features may be added in subsequent releases. Code Example: Demuxing WebP data to extract all the frames, ICC profile and EXIF/XMP metadata. WebPDemuxer* demux = WebPDemux(&webp_data); uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); // ... (Get information about the features present in the WebP file). uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); // ... (Iterate over all frames). WebPIterator iter; if (WebPDemuxGetFrame(demux, 1, &iter)) { do { // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), // ... and get other frame properties like width, height, offsets etc. // ... see 'struct WebPIterator' below for more info). } while (WebPDemuxNextFrame(&iter)); WebPDemuxReleaseIterator(&iter); } // ... (Extract metadata). WebPChunkIterator chunk_iter; if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); // ... (Consume the ICC profile in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); // ... (Consume the XMP metadata in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); WebPDemuxDelete(demux); For a detailed Demux API reference, please refer to the header file (src/webp/demux.h). Bugs: ===== Please report all bugs to our issue tracker: http://code.google.com/p/webp/issues Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/ Discuss: ======== Email: webp-discuss@webmproject.org Web: http://groups.google.com/a/webmproject.org/group/webp-discuss libwebp-0.4.0/depcomp0000755000014400001440000004755612255206714011451 0ustar #! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2011-12-04.11; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, # 2011 Free Software Foundation, Inc. # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test "$stat" = 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/ \1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/ / G p }' >> "$depfile" rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libwebp-0.4.0/install-sh0000755000014400001440000003325612255206714012070 0ustar #!/bin/sh # install - install a program, script, or datafile scriptversion=2011-01-19.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for `test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for `test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for `test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libwebp-0.4.0/configure0000755000014400001440000162514712255206713012001 0ustar #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for libwebp 0.4.0. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: http://code.google.com/p/webp/issues about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libwebp' PACKAGE_TARNAME='libwebp' PACKAGE_VERSION='0.4.0' PACKAGE_STRING='libwebp 0.4.0' PACKAGE_BUGREPORT='http://code.google.com/p/webp/issues' PACKAGE_URL='http://developers.google.com/speed/webp' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS BUILD_LIBWEBPDECODER_FALSE BUILD_LIBWEBPDECODER_TRUE WANT_DEMUX_FALSE WANT_DEMUX_TRUE WANT_MUX_FALSE WANT_MUX_TRUE USE_EXPERIMENTAL_CODE USE_SWAP_16BIT_CSP BUILD_GIF2WEBP_FALSE BUILD_GIF2WEBP_TRUE GIF_INCLUDES GIF_LIBS TIFF_INCLUDES TIFF_LIBS JPEG_INCLUDES JPEG_LIBS PNG_INCLUDES PNG_LIBS LIBPNG_CONFIG BUILD_VWEBP_FALSE BUILD_VWEBP_TRUE GL_INCLUDES GL_LIBS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC ax_pthread_config AM_CFLAGS pkgconfigdir AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED LIBTOOL am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC ac_ct_AR AR am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_silent_rules enable_everything with_pkgconfigdir enable_threading with_glincludedir with_gllibdir with_pngincludedir with_pnglibdir with_jpegincludedir with_jpeglibdir with_tiffincludedir with_tifflibdir with_gifincludedir with_giflibdir enable_wic enable_swap_16bit_csp enable_experimental enable_libwebpmux enable_libwebpdemux enable_libwebpdecoder ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libwebp 0.4.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libwebp] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libwebp 0.4.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0') --enable-everything Enable all optional targets. These can still be disabled with --disable-target --disable-threading Disable detection of thread support --disable-wic Disable Windows Imaging Component (WIC) detection. [default=auto] --enable-swap-16bit-csp Enable byte swap for 16 bit colorspaces --enable-experimental Activate experimental features --enable-libwebpmux Build libwebpmux [default=no] --enable-libwebpdemux Build libwebpdemux [default=no] --enable-libwebpdecoder Build libwebpdecoder [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pkgconfigdir=DIR Path to the pkgconfig directory [LIBDIR/pkgconfig] --with-glincludedir=DIR use GL includes from DIR --with-gllibdir=DIR use GL libraries from DIR --with-pngincludedir=DIR use PNG includes from DIR --with-pnglibdir=DIR use PNG libraries from DIR --with-jpegincludedir=DIR use JPEG includes from DIR --with-jpeglibdir=DIR use JPEG libraries from DIR --with-tiffincludedir=DIR use TIFF includes from DIR --with-tifflibdir=DIR use TIFF libraries from DIR --with-gifincludedir=DIR use GIF includes from DIR --with-giflibdir=DIR use GIF libraries from DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . libwebp home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libwebp configure 0.4.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## --------------------------------------------------- ## ## Report this to http://code.google.com/p/webp/issues ## ## --------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libwebp $as_me 0.4.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libwebp' VERSION='0.4.0' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: if test "x$CC" != xcc; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h fi # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' # Check whether --enable-everything was given. if test "${enable_everything+set}" = set; then : enableval=$enable_everything; test "${enable_libwebpdecoder+set}" = "set" || enable_libwebpdecoder=$enableval test "${enable_libwebpdemux+set}" = "set" || enable_libwebpdemux=$enableval test "${enable_libwebpmux+set}" = "set" || enable_libwebpmux=$enableval fi # Check whether --with-pkgconfigdir was given. if test "${with_pkgconfigdir+set}" = set; then : withval=$with_pkgconfigdir; pkgconfigdir="$withval" else pkgconfigdir='${libdir}/pkgconfig' fi SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wall" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wall" >&5 $as_echo_n "checking whether $CC supports -Wall... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wall" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wdeclaration-after-statement" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wdeclaration-after-statement" >&5 $as_echo_n "checking whether $CC supports -Wdeclaration-after-statement... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wdeclaration-after-statement" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wextra" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wextra" >&5 $as_echo_n "checking whether $CC supports -Wextra... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wextra" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wmissing-declarations" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wmissing-declarations" >&5 $as_echo_n "checking whether $CC supports -Wmissing-declarations... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wmissing-declarations" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wmissing-prototypes" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wmissing-prototypes" >&5 $as_echo_n "checking whether $CC supports -Wmissing-prototypes... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wmissing-prototypes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wold-style-definition" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wold-style-definition" >&5 $as_echo_n "checking whether $CC supports -Wold-style-definition... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wold-style-definition" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wshadow" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wshadow" >&5 $as_echo_n "checking whether $CC supports -Wshadow... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wshadow" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wunused-but-set-variable" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wunused-but-set-variable" >&5 $as_echo_n "checking whether $CC supports -Wunused-but-set-variable... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wunused-but-set-variable" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wunused" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wunused" >&5 $as_echo_n "checking whether $CC supports -Wunused... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wunused" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wvla" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wvla" >&5 $as_echo_n "checking whether $CC supports -Wvla... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } AM_CFLAGS="$AM_CFLAGS -Wvla" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" # Check whether --enable-threading was given. if test "${enable_threading+set}" = set; then : enableval=$enable_threading; else enable_threading=yes fi if test "$enable_threading" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for threading support..." >&5 $as_echo "$as_me: checking for threading support..." >&6;} ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 $as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_join (); int main () { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } ;; -*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 $as_echo_n "checking whether pthreads work with $flag... " >&6; } PTHREAD_CFLAGS="$flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ax_pthread_config+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ax_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" fi fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 $as_echo "$ax_pthread_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 $as_echo_n "checking for the pthreads library -l$flag... " >&6; } PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; } int main () { pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 $as_echo_n "checking for joinable pthread attribute... " >&6; } attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int attr = $attr; return attr /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : attr_name=$attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 $as_echo "$attr_name" >&6; } if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $attr_name _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 $as_echo_n "checking if more special flags are required for pthreads... " >&6; } flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else flag="-mt -D_REENTRANT" fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 $as_echo "${flag}" >&6; } if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 $as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = PTHREAD_PRIO_INHERIT; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_PTHREAD_PRIO_INHERIT=yes else ax_cv_PTHREAD_PRIO_INHERIT=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 $as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : $as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then for ac_prog in xlc_r cc_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PTHREAD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 $as_echo "$PTHREAD_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then $as_echo "#define WEBP_USE_THREAD 1" >>confdefs.h LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC" : else ax_pthread_ok=no enable_threading=no fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if threading is enabled... ${enable_threading-no}" >&5 $as_echo "$as_me: checking if threading is enabled... ${enable_threading-no}" >&6;} GL_INCLUDES=""; GL_LIBS="" # Check whether --with-glincludedir was given. if test "${with_glincludedir+set}" = set; then : withval=$with_glincludedir; GL_INCLUDES="-I$withval" fi # Check whether --with-gllibdir was given. if test "${with_gllibdir+set}" = set; then : withval=$with_gllibdir; GL_LIBS="-L$withval" fi SAVED_CPPFLAGS=$CPPFLAGS SAVED_LIBS=$LIBS CPPFLAGS="$GL_INCLUDES $CPPFLAGS" LIBS="$GL_LIBS $LIBS" glut_cflags="none" glut_ldflags="none" case $host_os in darwin*) # Special case for OSX builds. Append these to give the user a chance to # override with --with-gl* glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL" glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL" ;; esac GLUT_SAVED_CPPFLAGS="$CPPFLAGS" SAVED_IFS="$IFS" IFS="|" for flag in $glut_cflags; do # restore IFS immediately as the autoconf macros may need the default. IFS="$SAVED_IFS" unset ac_cv_header_GL_glut_h unset ac_cv_header_OpenGL_glut_h case $flag in none) ;; *) CPPFLAGS="$flag $CPPFLAGS";; esac for ac_header in GL/glut.h GLUT/glut.h OpenGL/glut.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF glut_headers=yes; test "$flag" = "none" || GL_INCLUDES="$CPPFLAGS"; break fi done CPPFLAGS="$GLUT_SAVED_CPPFLAGS" test "$glut_headers" = "yes" && break done IFS="$SAVED_IFS" if test "$glut_headers" = "yes"; then ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu GLUT_SAVED_LDFLAGS="$LDFLAGS" SAVED_IFS="$IFS" IFS="|" for flag in $glut_ldflags; do # restore IFS immediately as the autoconf macros may need the default. IFS="$SAVED_IFS" unset ac_cv_search_glBegin case $flag in none) ;; *) LDFLAGS="$flag $LDFLAGS";; esac # find libGL GL_SAVED_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing glBegin" >&5 $as_echo_n "checking for library containing glBegin... " >&6; } if ${ac_cv_search_glBegin+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char glBegin (); int main () { return glBegin (); ; return 0; } _ACEOF for ac_lib in '' GL OpenGL; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_glBegin=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_glBegin+:} false; then : break fi done if ${ac_cv_search_glBegin+:} false; then : else ac_cv_search_glBegin=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_glBegin" >&5 $as_echo "$ac_cv_search_glBegin" >&6; } ac_res=$ac_cv_search_glBegin if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi LIBS="$GL_SAVED_LIBS" # A direct link to libGL may not be necessary on e.g., linux. GLUT_SAVED_LIBS="$LIBS" for lib in "" "-lglut" "-lglut $ac_cv_search_glBegin"; do LIBS="$lib" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __cplusplus # define EXTERN_C extern "C" #else # define EXTERN_C #endif EXTERN_C char glOrtho(); EXTERN_C char glutMainLoop(); int main () { glOrtho(); glutMainLoop(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define WEBP_HAVE_GL 1" >>confdefs.h glut_support=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$glut_support" = "yes"; then GL_LIBS="$LDFLAGS $lib" break fi done LIBS="$GLUT_SAVED_LIBS" LDFLAGS="$GLUT_SAVED_LDFLAGS" test "$glut_support" = "yes" && break done IFS="$SAVED_IFS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi CPPFLAGS=$SAVED_CPPFLAGS LIBS=$SAVED_LIBS if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then build_vwebp=yes fi if test "$build_vwebp" = "yes"; then BUILD_VWEBP_TRUE= BUILD_VWEBP_FALSE='#' else BUILD_VWEBP_TRUE='#' BUILD_VWEBP_FALSE= fi PNG_INCLUDES=""; PNG_LIBS="" for ac_prog in libpng-config libpng15-config libpng14-config libpng12-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LIBPNG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $LIBPNG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_LIBPNG_CONFIG="$LIBPNG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LIBPNG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LIBPNG_CONFIG=$ac_cv_path_LIBPNG_CONFIG if test -n "$LIBPNG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBPNG_CONFIG" >&5 $as_echo "$LIBPNG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LIBPNG_CONFIG" && break done if test -n "$LIBPNG_CONFIG"; then PNG_INCLUDES=`$LIBPNG_CONFIG --cflags` PNG_PREFIX=`$LIBPNG_CONFIG --prefix` if test "${PNG_PREFIX}/lib" != "/usr/lib" ; then PNG_LIBS="-L${PNG_PREFIX}/lib" fi PNG_LIBS="$PNG_LIBS `$LIBPNG_CONFIG --libs`" fi # Check whether --with-pngincludedir was given. if test "${with_pngincludedir+set}" = set; then : withval=$with_pngincludedir; PNG_INCLUDES="-I$withval" fi # Check whether --with-pnglibdir was given. if test "${with_pnglibdir+set}" = set; then : withval=$with_pnglibdir; PNG_LIBS="-L$withval" fi SAVED_CPPFLAGS=$CPPFLAGS SAVED_LIBS=$LIBS CPPFLAGS="$PNG_INCLUDES $CPPFLAGS" LIBS="$PNG_LIBS $LIBS" ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" if test "x$ac_cv_header_png_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing png_get_libpng_ver" >&5 $as_echo_n "checking for library containing png_get_libpng_ver... " >&6; } if ${ac_cv_search_png_get_libpng_ver+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_get_libpng_ver (); int main () { return png_get_libpng_ver (); ; return 0; } _ACEOF for ac_lib in '' png; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $MATH_LIBS $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_png_get_libpng_ver=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_png_get_libpng_ver+:} false; then : break fi done if ${ac_cv_search_png_get_libpng_ver+:} false; then : else ac_cv_search_png_get_libpng_ver=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_png_get_libpng_ver" >&5 $as_echo "$ac_cv_search_png_get_libpng_ver" >&6; } ac_res=$ac_cv_search_png_get_libpng_ver if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" test "$ac_cv_search_png_get_libpng_ver" = "none required" \ || PNG_LIBS="$PNG_LIBS $ac_cv_search_png_get_libpng_ver" PNG_INCLUDES="$PNG_INCLUDES -DWEBP_HAVE_PNG" $as_echo "#define WEBP_HAVE_PNG 1" >>confdefs.h png_support=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Optional png library not found" >&5 $as_echo "$as_me: WARNING: Optional png library not found" >&2;} PNG_LIBS="" PNG_INCLUDES="" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: png library not available - no png.h" >&5 $as_echo "$as_me: WARNING: png library not available - no png.h" >&2;} PNG_LIBS="" PNG_INCLUDES="" fi CPPFLAGS=$SAVED_CPPFLAGS LIBS=$SAVED_LIBS JPEG_INCLUDES=""; JPEG_LIBS="" # Check whether --with-jpegincludedir was given. if test "${with_jpegincludedir+set}" = set; then : withval=$with_jpegincludedir; JPEG_INCLUDES="-I$withval" fi # Check whether --with-jpeglibdir was given. if test "${with_jpeglibdir+set}" = set; then : withval=$with_jpeglibdir; JPEG_LIBS="-L$withval" fi SAVED_CPPFLAGS=$CPPFLAGS SAVED_LIBS=$LIBS CPPFLAGS="$JPEG_INCLUDES $CPPFLAGS" LIBS="$JPEG_LIBS $LIBS" ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" if test "x$ac_cv_header_jpeglib_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_set_defaults in -ljpeg" >&5 $as_echo_n "checking for jpeg_set_defaults in -ljpeg... " >&6; } if ${ac_cv_lib_jpeg_jpeg_set_defaults+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljpeg $MATH_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jpeg_set_defaults (); int main () { return jpeg_set_defaults (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_jpeg_jpeg_set_defaults=yes else ac_cv_lib_jpeg_jpeg_set_defaults=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_set_defaults" >&5 $as_echo "$ac_cv_lib_jpeg_jpeg_set_defaults" >&6; } if test "x$ac_cv_lib_jpeg_jpeg_set_defaults" = xyes; then : JPEG_LIBS="$JPEG_LIBS -ljpeg" JPEG_INCLUDES="$JPEG_INCLUDES -DWEBP_HAVE_JPEG" $as_echo "#define WEBP_HAVE_JPEG 1" >>confdefs.h jpeg_support=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Optional jpeg library not found" >&5 $as_echo "$as_me: WARNING: Optional jpeg library not found" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: jpeg library not available - no jpeglib.h" >&5 $as_echo "$as_me: WARNING: jpeg library not available - no jpeglib.h" >&2;} fi CPPFLAGS=$SAVED_CPPFLAGS LIBS=$SAVED_LIBS TIFF_INCLUDES=""; TIFF_LIBS="" # Check whether --with-tiffincludedir was given. if test "${with_tiffincludedir+set}" = set; then : withval=$with_tiffincludedir; TIFF_INCLUDES="-I$withval" fi # Check whether --with-tifflibdir was given. if test "${with_tifflibdir+set}" = set; then : withval=$with_tifflibdir; TIFF_LIBS="-L$withval" fi SAVED_CPPFLAGS=$CPPFLAGS SAVED_LIBS=$LIBS CPPFLAGS="$TIFF_INCLUDES $CPPFLAGS" LIBS="$TIFF_LIBS $LIBS" ac_fn_c_check_header_mongrel "$LINENO" "tiffio.h" "ac_cv_header_tiffio_h" "$ac_includes_default" if test "x$ac_cv_header_tiffio_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFGetVersion in -ltiff" >&5 $as_echo_n "checking for TIFFGetVersion in -ltiff... " >&6; } if ${ac_cv_lib_tiff_TIFFGetVersion+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltiff $MATH_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TIFFGetVersion (); int main () { return TIFFGetVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tiff_TIFFGetVersion=yes else ac_cv_lib_tiff_TIFFGetVersion=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFGetVersion" >&5 $as_echo "$ac_cv_lib_tiff_TIFFGetVersion" >&6; } if test "x$ac_cv_lib_tiff_TIFFGetVersion" = xyes; then : TIFF_LIBS="$TIFF_LIBS -ltiff" TIFF_INCLUDES="$TIFF_INCLUDES -DWEBP_HAVE_TIFF" $as_echo "#define WEBP_HAVE_TIFF 1" >>confdefs.h tiff_support=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Optional tiff library not found" >&5 $as_echo "$as_me: WARNING: Optional tiff library not found" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: tiff library not available - no tiffio.h" >&5 $as_echo "$as_me: WARNING: tiff library not available - no tiffio.h" >&2;} fi CPPFLAGS=$SAVED_CPPFLAGS LIBS=$SAVED_LIBS GIF_INCLUDES=""; GIF_LIBS="" # Check whether --with-gifincludedir was given. if test "${with_gifincludedir+set}" = set; then : withval=$with_gifincludedir; GIF_INCLUDES="-I$withval" fi # Check whether --with-giflibdir was given. if test "${with_giflibdir+set}" = set; then : withval=$with_giflibdir; GIF_LIBS="-L$withval" fi SAVED_CPPFLAGS=$CPPFLAGS SAVED_LIBS=$LIBS CPPFLAGS="$GIF_INCLUDES $CPPFLAGS" LIBS="$GIF_LIBS $LIBS" ac_fn_c_check_header_mongrel "$LINENO" "gif_lib.h" "ac_cv_header_gif_lib_h" "$ac_includes_default" if test "x$ac_cv_header_gif_lib_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DGifOpenFileHandle in -lgif" >&5 $as_echo_n "checking for DGifOpenFileHandle in -lgif... " >&6; } if ${ac_cv_lib_gif_DGifOpenFileHandle+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgif $MATH_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char DGifOpenFileHandle (); int main () { return DGifOpenFileHandle (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gif_DGifOpenFileHandle=yes else ac_cv_lib_gif_DGifOpenFileHandle=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_DGifOpenFileHandle" >&5 $as_echo "$ac_cv_lib_gif_DGifOpenFileHandle" >&6; } if test "x$ac_cv_lib_gif_DGifOpenFileHandle" = xyes; then : GIF_LIBS="$GIF_LIBS -lgif" $as_echo "#define WEBP_HAVE_GIF 1" >>confdefs.h gif_support=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Optional gif library not found" >&5 $as_echo "$as_me: WARNING: Optional gif library not found" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gif library not available - no gif_lib.h" >&5 $as_echo "$as_me: WARNING: gif library not available - no gif_lib.h" >&2;} fi CPPFLAGS=$SAVED_CPPFLAGS LIBS=$SAVED_LIBS if test "$gif_support" = "yes" -a \ "$enable_libwebpmux" = "yes"; then build_gif2webp=yes fi if test "${build_gif2webp}" = "yes"; then BUILD_GIF2WEBP_TRUE= BUILD_GIF2WEBP_FALSE='#' else BUILD_GIF2WEBP_TRUE='#' BUILD_GIF2WEBP_FALSE= fi # Check whether --enable-wic was given. if test "${enable_wic+set}" = set; then : enableval=$enable_wic; else enable_wic=yes fi if test "$target_os" = "mingw32" -a "$enable_wic" = "yes"; then for ac_header in wincodec.h shlwapi.h windows.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "$ac_cv_header_wincodec_h" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows Imaging Component support" >&5 $as_echo_n "checking for Windows Imaging Component support... " >&6; } SAVED_LIBS=$LIBS LIBS="-lshlwapi -lole32 $LIBS" # match include structure from [cd]webp.c wic_headers=" #define INITGUID #define CINTERFACE #define COBJMACROS #define _WIN32_IE 0x500 #include #include #include " # test for functions from each lib and the GUID is created properly wic_main=" int main(void) { CLSID_WICImagingFactory; CoInitialize(NULL); SHCreateStreamOnFile(NULL, 0, NULL); return 0; } " ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $wic_headers $wic_main _ACEOF if ac_fn_c_try_link "$LINENO"; then : wic_support=yes else wic_support=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu test "$wic_support" = "yes" || LIBS=$SAVED_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${wic_support-no}" >&5 $as_echo "${wic_support-no}" >&6; } fi fi USE_SWAP_16BIT_CSP="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-swap-16bit-csp option is specified" >&5 $as_echo_n "checking if --enable-swap-16bit-csp option is specified... " >&6; } # Check whether --enable-swap-16bit-csp was given. if test "${enable_swap_16bit_csp+set}" = set; then : enableval=$enable_swap_16bit_csp; fi if test "$enable_swap_16bit_csp" = "yes"; then USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_swap_16bit_csp-no}" >&5 $as_echo "${enable_swap_16bit_csp-no}" >&6; } USE_EXPERIMENTAL_CODE="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-experimental option is specified" >&5 $as_echo_n "checking if --enable-experimental option is specified... " >&6; } # Check whether --enable-experimental was given. if test "${enable_experimental+set}" = set; then : enableval=$enable_experimental; fi if test "$enable_experimental" = "yes"; then $as_echo "#define WEBP_EXPERIMENTAL_FEATURES 1" >>confdefs.h USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_experimental-no}" >&5 $as_echo "${enable_experimental-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libwebpmux is to be built" >&5 $as_echo_n "checking whether libwebpmux is to be built... " >&6; } # Check whether --enable-libwebpmux was given. if test "${enable_libwebpmux+set}" = set; then : enableval=$enable_libwebpmux; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_libwebpmux-no}" >&5 $as_echo "${enable_libwebpmux-no}" >&6; } if test "$enable_libwebpmux" = "yes"; then WANT_MUX_TRUE= WANT_MUX_FALSE='#' else WANT_MUX_TRUE='#' WANT_MUX_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libwebpdemux is to be built" >&5 $as_echo_n "checking whether libwebpdemux is to be built... " >&6; } # Check whether --enable-libwebpdemux was given. if test "${enable_libwebpdemux+set}" = set; then : enableval=$enable_libwebpdemux; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_libwebpdemux-no}" >&5 $as_echo "${enable_libwebpdemux-no}" >&6; } if test "$enable_libwebpdemux" = "yes"; then WANT_DEMUX_TRUE= WANT_DEMUX_FALSE='#' else WANT_DEMUX_TRUE='#' WANT_DEMUX_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether decoder library is to be built" >&5 $as_echo_n "checking whether decoder library is to be built... " >&6; } # Check whether --enable-libwebpdecoder was given. if test "${enable_libwebpdecoder+set}" = set; then : enableval=$enable_libwebpdecoder; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_libwebpdecoder-no}" >&5 $as_echo "${enable_libwebpdecoder-no}" >&6; } if test "$enable_libwebpdecoder" = "yes"; then BUILD_LIBWEBPDECODER_TRUE= BUILD_LIBWEBPDECODER_FALSE='#' else BUILD_LIBWEBPDECODER_TRUE='#' BUILD_LIBWEBPDECODER_FALSE= fi ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files Makefile src/Makefile man/Makefile examples/Makefile src/dec/Makefile src/enc/Makefile src/dsp/Makefile src/demux/Makefile src/mux/Makefile src/utils/Makefile src/libwebp.pc src/libwebpdecoder.pc src/demux/libwebpdemux.pc src/mux/libwebpmux.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_VWEBP_TRUE}" && test -z "${BUILD_VWEBP_FALSE}"; then as_fn_error $? "conditional \"BUILD_VWEBP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_GIF2WEBP_TRUE}" && test -z "${BUILD_GIF2WEBP_FALSE}"; then as_fn_error $? "conditional \"BUILD_GIF2WEBP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WANT_MUX_TRUE}" && test -z "${WANT_MUX_FALSE}"; then as_fn_error $? "conditional \"WANT_MUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WANT_DEMUX_TRUE}" && test -z "${WANT_DEMUX_FALSE}"; then as_fn_error $? "conditional \"WANT_DEMUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_LIBWEBPDECODER_TRUE}" && test -z "${BUILD_LIBWEBPDECODER_FALSE}"; then as_fn_error $? "conditional \"BUILD_LIBWEBPDECODER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libwebp $as_me 0.4.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to . libwebp home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libwebp config.status 0.4.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "src/dec/Makefile") CONFIG_FILES="$CONFIG_FILES src/dec/Makefile" ;; "src/enc/Makefile") CONFIG_FILES="$CONFIG_FILES src/enc/Makefile" ;; "src/dsp/Makefile") CONFIG_FILES="$CONFIG_FILES src/dsp/Makefile" ;; "src/demux/Makefile") CONFIG_FILES="$CONFIG_FILES src/demux/Makefile" ;; "src/mux/Makefile") CONFIG_FILES="$CONFIG_FILES src/mux/Makefile" ;; "src/utils/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/Makefile" ;; "src/libwebp.pc") CONFIG_FILES="$CONFIG_FILES src/libwebp.pc" ;; "src/libwebpdecoder.pc") CONFIG_FILES="$CONFIG_FILES src/libwebpdecoder.pc" ;; "src/demux/libwebpdemux.pc") CONFIG_FILES="$CONFIG_FILES src/demux/libwebpdemux.pc" ;; "src/mux/libwebpmux.pc") CONFIG_FILES="$CONFIG_FILES src/mux/libwebpmux.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: WebP Configuration Summary -------------------------- Shared libraries: ${enable_shared} Static libraries: ${enable_static} Threaded decode: ${enable_threading-no} libwebp: yes libwebpdecoder: ${enable_libwebpdecoder-no} libwebpdemux: ${enable_libwebpdemux-no} libwebpmux: ${enable_libwebpmux-no} Tools: cwebp : yes Input format support ==================== JPEG : ${jpeg_support-no} PNG : ${png_support-no} TIFF : ${tiff_support-no} WIC : ${wic_support-no} dwebp : yes Output format support ===================== PNG : ${png_support-no} WIC : ${wic_support-no} GIF support : ${gif_support-no} gif2webp : ${build_gif2webp-no} webpmux : ${enable_libwebpmux-no} vwebp : ${build_vwebp-no} " >&5 $as_echo "$as_me: WebP Configuration Summary -------------------------- Shared libraries: ${enable_shared} Static libraries: ${enable_static} Threaded decode: ${enable_threading-no} libwebp: yes libwebpdecoder: ${enable_libwebpdecoder-no} libwebpdemux: ${enable_libwebpdemux-no} libwebpmux: ${enable_libwebpmux-no} Tools: cwebp : yes Input format support ==================== JPEG : ${jpeg_support-no} PNG : ${png_support-no} TIFF : ${tiff_support-no} WIC : ${wic_support-no} dwebp : yes Output format support ===================== PNG : ${png_support-no} WIC : ${wic_support-no} GIF support : ${gif_support-no} gif2webp : ${build_gif2webp-no} webpmux : ${enable_libwebpmux-no} vwebp : ${build_vwebp-no} " >&6;} libwebp-0.4.0/ar-lib0000755000014400001440000001305312255206714011151 0ustar #! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-01-30.22; # UTC # Copyright (C) 2010, 2012 Free Software Foundation, Inc. # Written by Peter Rosin . # # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. # # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l*) lib=${1#-l} found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes set x "$@" "$dir/$lib.dll.lib" break fi if test -f "$dir/$lib.lib"; then found=yes set x "$@" "$dir/$lib.lib" break fi done IFS=$save_IFS test "$found" != yes && set x "$@" "$lib.lib" shift ;; -L*) func_file_conv "${1#-L}" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libwebp-0.4.0/man/0000755000014400001440000000000012255206714010626 5ustar libwebp-0.4.0/man/Makefile.in0000644000014400001440000003424112255206714012677 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ @WANT_MUX_TRUE@am__append_1 = webpmux.1 @BUILD_GIF2WEBP_TRUE@am__append_2 = gif2webp.1 subdir = man DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ man_MANS = cwebp.1 dwebp.1 $(am__append_1) $(am__append_2) EXTRA_DIST = $(man_MANS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign man/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @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 $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)"; 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-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool 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-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-man uninstall-man1 # 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: libwebp-0.4.0/man/dwebp.10000644000014400001440000000744412255002107012010 0ustar .\" Hey, EMACS: -*- nroff -*- .TH DWEBP 1 "December 12, 2013" .SH NAME dwebp \- decompress a WebP file to an image file .SH SYNOPSIS .B dwebp .RI [ options ] " input_file.webp .br .SH DESCRIPTION This manual page documents the .B dwebp command. .PP \fBdwebp\fP decompresses WebP files into PNG, PAM, PPM or PGM images. .SH OPTIONS The basic options are: .TP .B \-h Print usage summary. .TP .B \-version Print the version number (as major.minor.revision) and exit. .TP .BI \-o " string Specify the name of the output file (as PNG format by default). Using "-" as output name will direct output to 'stdout'. .TP .B \-bmp Change the output format to uncompressed BMP. .TP .B \-tiff Change the output format to uncompressed TIFF. .TP .B \-pam Change the output format to PAM (retains alpha). .TP .B \-ppm Change the output format to PPM (discards alpha). .TP .B \-pgm Change the output format to PGM. The output consists of luma/chroma samples instead of RGB, using the IMC4 layout. This option is mainly for verification and debugging purposes. .TP .B \-yuv Change the output format to raw YUV. The output consists of luma/chroma-U/chroma-V samples instead of RGB, saved sequentially as individual planes. This option is mainly for verification and debugging purposes. .TP .B \-nofancy Don't use the fancy upscaler for YUV420. This may lead to jaggy edges (especially the red ones), but should be faster. .TP .B \-nofilter Don't use the in-loop filtering process even if it is required by the bitstream. This may produce visible blocks on the non-compliant output, but it will make the decoding faster. .TP .B \-dither " strength Specify a dithering \fBstrength\fP between 0 and 100. Dithering is a post-processing effect applied to chroma components in lossy compression. It helps by smoothing gradients and avoiding banding artifacts. .TP .B \-nodither Disable all dithering (default). .TP .B \-mt Use multi-threading for decoding, if possible. .TP .BI \-crop " x_position y_position width height Crop the decoded picture to a rectangle with top-left corner at coordinates (\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP. This cropping area must be fully contained within the source rectangle. The top-left corner will be snapped to even coordinates if needed. This option is meant to reduce the memory needed for cropping large images. Note: the cropping is applied \fIbefore\fP any scaling. .TP .BI \-scale " width height Rescale the decoded picture to dimension \fBwidth\fP x \fBheight\fP. This option is mostly intended to reducing the memory needed to decode large images, when only a small version is needed (thumbnail, preview, etc.). Note: scaling is applied \fIafter\fP cropping. .TP .B \-v Print extra information (decoding time in particular). .TP .B \-noasm Disable all assembly optimizations. .SH BUGS Please report all bugs to our issue tracker: http://code.google.com/p/webp/issues .br Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/ .SH EXAMPLES dwebp picture.webp \-o output.png .br dwebp picture.webp \-ppm \-o output.ppm .br dwebp \-o output.ppm \-\- \-\-\-picture.webp .SH AUTHORS \fBdwebp\fP was written by the WebP team. .br The latest source tree is available at http://www.webmproject.org/code .PP This manual page was written by Pascal Massimino , for the Debian project (and may be used by others). .SH SEE ALSO .BR cwebp (1), .BR gif2webp (1), .BR webpmux (1) .br Please refer to http://developers.google.com/speed/webp/ for additional information. .SS Output file format details PAM: http://netpbm.sourceforge.net/doc/pam.html .br PGM: http://netpbm.sourceforge.net/doc/pgm.html .br PPM: http://netpbm.sourceforge.net/doc/ppm.html .br PNG: http://www.libpng.org/pub/png/png-sitemap.html#info libwebp-0.4.0/man/cwebp.10000644000014400001440000002513212255002107012001 0ustar .\" Hey, EMACS: -*- nroff -*- .TH CWEBP 1 "December 12, 2013" .SH NAME cwebp \- compress an image file to a WebP file .SH SYNOPSIS .B cwebp .RI [ options ] " input_file \-o output_file.webp .br .SH DESCRIPTION This manual page documents the .B cwebp command. .PP \fBcwebp\fP compresses an image using the WebP format. Input format can be either PNG, JPEG, TIFF or raw Y'CbCr samples. .SH OPTIONS The basic options are: .TP .BI \-o " string Specify the name of the output WebP file. If omitted, \fBcwebp\fP will perform compression but only report statistics. .TP .B \-h, \-help A short usage summary. .TP .B \-H, \-longhelp A summary of all the possible options. .TP .B \-version Print the version number (as major.minor.revision) and exit. .TP .BI \-q " float Specify the compression factor for RGB channels between 0 and 100. The default is 75. .br In case of lossy compression (default), a small factor produces a smaller file with lower quality. Best quality is achieved by using a value of 100. .br In case of lossless compression (specified by the \-lossless option), a small factor enables faster compression speed, but produces a larger file. Maximum compression is achieved by using a value of 100. .TP .BI \-alpha_q " int Specify the compression factor for alpha compression between 0 and 100. Lossless compression of alpha is achieved using a value of 100, while the lower values result in a lossy compression. The default is 100. .TP .BI \-f " int Specify the strength of the deblocking filter, between 0 (no filtering) and 100 (maximum filtering). A value of 0 will turn off any filtering. Higher value will increase the strength of the filtering process applied after decoding the picture. The higher the value the smoother the picture will appear. Typical values are usually in the range of 20 to 50. .TP .BI \-preset " string Specify a set of pre-defined parameters to suit a particular type of source material. Possible values are: \fBdefault\fP, \fBphoto\fP, \fBpicture\fP, \fBdrawing\fP, \fBicon\fP, \fBtext\fP. Since \fB\-preset\fP overwrites the other parameters' values (except the \fB\-q\fP one), this option should preferably appear first in the order of the arguments. .TP .BI \-sns " int Specify the amplitude of the spatial noise shaping. Spatial noise shaping (or \fBsns\fP for short) refers to a general collection of built-in algorithms used to decide which area of the picture should use relatively less bits, and where else to better transfer these bits. The possible range goes from 0 (algorithm is off) to 100 (the maximal effect). The default value is 80. .TP .BI \-m " int Specify the compression method to use. This parameter controls the trade off between encoding speed and the compressed file size and quality. Possible values range from 0 to 6. Default value is 4. When higher values are used, the encoder will spend more time inspecting additional encoding possibilities and decide on the quality gain. Lower value can result in faster processing time at the expense of larger file size and lower compression quality. .TP .B \-jpeg_like Change the internal parameter mapping to better match the expected size of JPEG compression. This flag will generally produce an output file of similar size to its JPEG equivalent (for the same \fB\-q\fP setting), but with less visual distortion. .TP .B \-mt Use multi-threading for encoding, if possible. This option is only effective when using lossy compression on a source with a transparency channel. .TP .B \-low_memory Reduce memory usage of lossy encoding by saving four times the compressed size (typically). This will make the encoding slower and the output slightly different in size and distortion. This flag is only effective for methods 3 and up, and is off by default. Note that leaving this flag off will have some side effects on the bitstream: it forces certain bitstream features like number of partitions (forced to 1). Note that a more detailed report of bitstream size is printed by \fBcwebp\fP when using this option. .TP .B \-af Turns auto-filter on. This algorithm will spend additional time optimizing the filtering strength to reach a well-balanced quality. .SH ADDITIONAL OPTIONS More advanced options are: .TP .BI \-sharpness " int Specify the sharpness of the filtering (if used). Range is 0 (sharpest) to 7 (least sharp). Default is 0. .TP .B \-strong Use strong filtering (if filtering is being used thanks to the \fB\-f\fP option). Strong filtering is on by default. .TP .B \-nostrong Disable strong filtering (if filtering is being used thanks to the \fB\-f\fP option) and use simple filtering instead. .TP .BI \-segments " int Change the number of partitions to use during the segmentation of the sns algorithm. Segments should be in range 1 to 4. Default value is 4. This option has no effect for methods 3 and up, unless \fB\-low_memory\fP is used. .TP .BI \-partition_limit " int Degrade quality by limiting the number of bits used by some macroblocks. Range is 0 (no degradation, the default) to 100 (full degradation). Useful values are usually around 30-70 for moderately large images. In the VP8 format, the so-called control partition has a limit of 512k and is used to store the following information: whether the macroblock is skipped, which segment it belongs to, whether it is coded as intra 4x4 or intra 16x16 mode, and finally the prediction modes to use for each of the sub-blocks. For a very large image, 512k only leaves room to few bits per 16x16 macroblock. The absolute minimum is 4 bits per macroblock. Skip, segment, and mode information can use up almost all these 4 bits (although the case is unlikely), which is problematic for very large images. The partition_limit factor controls how frequently the most bit-costly mode (intra 4x4) will be used. This is useful in case the 512k limit is reached and the following message is displayed: \fIError code: 6 (PARTITION0_OVERFLOW: Partition #0 is too big to fit 512k)\fP. If using \fB-partition_limit\fP is not enough to meet the 512k constraint, one should use less segments in order to save more header bits per macroblock. See the \fB-segments\fP option. .TP .BI \-size " int Specify a target size (in bytes) to try and reach for the compressed output. Compressor will make several pass of partial encoding in order to get as close as possible to this target. .TP .BI \-psnr " float Specify a target PSNR (in dB) to try and reach for the compressed output. Compressor will make several pass of partial encoding in order to get as close as possible to this target. .TP .BI \-pass " int Set a maximum number of passes to use during the dichotomy used by options \fB\-size\fP or \fB\-psnr\fP. Maximum value is 10. .TP .BI \-resize " width height Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP. If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0, the value will be calculated preserving the aspect-ratio. .TP .BI \-crop " x_position y_position width height Crop the source to a rectangle with top-left corner at coordinates (\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP. This cropping area must be fully contained within the source rectangle. .TP .BI \-s " width height Specify that the input file actually consists of raw Y'CbCr samples following the ITU-R BT.601 recommendation, in 4:2:0 linear format. The luma plane has size \fBwidth\fP x \fBheight\fP. .TP .BI \-map " int Output additional ASCII-map of encoding information. Possible map values range from 1 to 6. This is only meant to help debugging. .TP .BI \-pre " int Specify some pre-processing steps. Using a value of '2' will trigger quality-dependent pseudo-random dithering during RGBA->YUVA conversion (lossy compression only). .TP .BI \-alpha_filter " string Specify the predictive filtering method for the alpha plane. One of 'none', \&'fast' or 'best', in increasing complexity and slowness order. Default is \&'fast'. Internally, alpha filtering is performed using four possible predictions (none, horizontal, vertical, gradient). The 'best' mode will try each mode in turn and pick the one which gives the smaller size. The 'fast' mode will just try to form an a-priori guess without testing all modes. .TP .BI \-alpha_method " int Specify the algorithm used for alpha compression: 0 or 1. Algorithm 0 denotes no compression, 1 uses WebP lossless format for compression. The default is 1. .TP .B \-alpha_cleanup Modify unseen RGB values under fully transparent area, to help compressibility. The default is off. .TP .BI \-blend_alpha " int This option blends the alpha channel (if present) with the source using the background color specified in hexadecimal as 0xrrggbb. The alpha channel is afterward reset to the opaque value 255. .TP .B \-noalpha Using this option will discard the alpha channel. .TP .B \-lossless Encode the image without any loss. .TP .BI \-hint " string Specify the hint about input image type. Possible values are: \fBphoto\fP, \fBpicture\fP or \fBgraph\fP. .TP .BI \-metadata " string A comma separated list of metadata to copy from the input to the output if present. Valid values: \fBall\fP, \fBnone\fP, \fBexif\fP, \fBicc\fP, \fBxmp\fP. The default is \fBnone\fP. Note: each input format may not support all combinations. .TP .B \-noasm Disable all assembly optimizations. .TP .B \-v Print extra information (encoding time in particular). .TP .B \-print_psnr Compute and report average PSNR (Peak-Signal-To-Noise ratio). .TP .B \-print_ssim Compute and report average SSIM (structural similarity metric, see http://en.wikipedia.org/wiki/SSIM for additional details). .TP .B \-print_lsim Compute and report local similarity metric (sum of lowest error amongst the collocated pixel neighbors). .TP .B \-progress Report encoding progress in percent. .TP .B \-quiet Do not print anything. .TP .B \-short Only print brief information (output file size and PSNR) for testing purpose. .SH BUGS Please report all bugs to our issue tracker: http://code.google.com/p/webp/issues .br Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/ .SH EXAMPLES cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp .br cwebp \-q 70 picture_with_alpha.png \-o picture_with_alpha.webp .br cwebp \-sns 70 \-f 50 \-size 60000 picture.png \-o picture.webp .br cwebp \-o picture.webp \-\- \-\-\-picture.png .SH AUTHORS \fBcwebp\fP was written by the WebP team. .br The latest source tree is available at http://www.webmproject.org/code .PP This manual page was written by Pascal Massimino , for the Debian project (and may be used by others). .SH SEE ALSO .BR dwebp (1), .BR gif2webp (1) .br Please refer to http://developers.google.com/speed/webp/ for additional information. libwebp-0.4.0/man/webpmux.10000644000014400001440000001027012255002107012365 0ustar .\" Hey, EMACS: -*- nroff -*- .TH WEBPMUX 1 "December 17, 2013" .SH NAME webpmux \- command line tool to create WebP Mux/container file. .SH SYNOPSIS .B webpmux \-get .I GET_OPTIONS .I INPUT .B \-o .I OUTPUT .br .B webpmux \-set .I SET_OPTIONS .I INPUT .B \-o .I OUTPUT .br .B webpmux \-strip .I STRIP_OPTIONS .I INPUT .B \-o .I OUTPUT .br .B webpmux \-frame .I FRAME_OPTIONS .B [ \-frame ... ] [ \-loop .I LOOP_COUNT .B ] .br .RS 8 .B [ \-bgcolor .I BACKGROUND_COLOR .B ] \-o .I OUTPUT .RE .br .B webpmux \-info .I INPUT .br .B webpmux [\-h|\-help] .br .B webpmux \-version .SH DESCRIPTION This manual page documents the .B webpmux command. .PP \fBwebpmux\fP can be used to create a WebP container file and extract/strip relevant data from the container file. .SH OPTIONS .SS GET_OPTIONS (\-get): .TP .B icc Get ICC profile. .TP .B exif Get EXIF metadata. .TP .B xmp Get XMP metadata. .TP .BI frame " n Get nth frame. .SS SET_OPTIONS (\-set) .TP .BI icc " file.icc Set ICC profile. .P Where: 'file.icc' contains the ICC profile to be set. .TP .BI exif " file.exif Set EXIF metadata. .P Where: 'file.exif' contains the EXIF metadata to be set. .TP .BI xmp " file.xmp Set XMP metadata. .P Where: 'file.xmp' contains the XMP metadata to be set. .SS STRIP_OPTIONS (\-strip) .TP .B icc Strip ICC profile. .TP .B exif Strip EXIF metadata. .TP .B xmp Strip XMP metadata. .SS FRAME_OPTIONS (\-frame) .TP .I file_i +di[+xi+yi[+mi[bi]]] Where: 'file_i' is the i'th frame (WebP format), 'xi','yi' specify the image offset for this frame, 'di' is the pause duration before next frame, 'mi' is the dispose method for this frame (0 for NONE or 1 for BACKGROUND) and 'bi' is the blending method for this frame (+b for BLEND or -b for NO_BLEND). Argument 'bi' can be omitted and will default to +b (BLEND). Also, 'mi' can be omitted if 'bi' is omitted and will default to 0 (NONE). Finally, if 'mi' and 'bi' are omitted then 'xi' and 'yi' can be omitted and will default to +0+0. .TP .BI \-loop " n Loop the frames n number of times. 0 indicates the frames should loop forever. Valid range is 0 to 65535 [Default: 0 (infinite)]. .TP .BI \-bgcolor " A,R,G,B Background color of the canvas. .br where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying the Alpha, Red, Green and Blue component values respectively [Default: 255,255,255,255]. .SS INPUT .TP Input file in WebP format. .SS OUTPUT (\-o) .TP Output file in WebP format. .SS Note: .TP The nature of EXIF, XMP and ICC data is not checked and is assumed to be valid. .SH BUGS Please report all bugs to our issue tracker: http://code.google.com/p/webp/issues .br Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/ .SH EXAMPLES webpmux \-set icc image_profile.icc in.webp \-o icc_container.webp .br webpmux \-get icc icc_container.webp \-o image_profile.icc .br webpmux \-strip icc icc_container.webp \-o without_icc.webp .br webpmux \-set xmp image_metadata.xmp in.webp \-o xmp_container.webp .br webpmux \-get xmp xmp_container.webp \-o image_metadata.xmp .br webpmux \-strip xmp xmp_container.webp \-o without_xmp.webp .br webpmux \-set exif image_metadata.exif in.webp \-o exif_container.webp .br webpmux \-get exif exif_container.webp \-o image_metadata.exif .br webpmux \-strip exif exif_container.webp \-o without_exif.webp .br webpmux \-frame anim_1.webp +100 \-frame anim_2.webp +100+50+50 .br .RS 8 \-frame anim_2.webp +100+50+50+1+b \-loop 10 \-bgcolor 255,255,255,255 .br .RS 8 \-o anim_container.webp .RE .br webpmux \-get frame 2 anim_container.webp \-o frame_2.webp .br webpmux \-set icc image_profile.icc \-o icc_container.webp \-\- \-\-\-in.webp .br webpmux \-get icc \-o image_profile.icc \-\- \-\-\-icc_container.webp .br webpmux \-strip icc \-o without_icc.webp \-\- \-\-\-icc_container.webp .SH AUTHORS \fBwebpmux\fP is written by the WebP team. .br The latest source tree is available at http://www.webmproject.org/code .PP This manual page was written by Vikas Arora , for the Debian project (and may be used by others). .SH SEE ALSO .BR cwebp (1), .BR dwebp (1), .BR gif2webp (1) .br Please refer to http://developers.google.com/speed/webp/ for additional information. libwebp-0.4.0/man/gif2webp.10000644000014400001440000001100712255002107012402 0ustar .\" Hey, EMACS: -*- nroff -*- .TH GIF2WEBP 1 "December 17, 2013" .SH NAME gif2webp \- Convert a GIF image to WebP .SH SYNOPSIS .B gif2webp .RI [ options ] " input_file.gif \-o output_file.webp .br .SH DESCRIPTION This manual page documents the .B gif2webp command. .PP \fBgif2webp\fP converts a GIF image to a WebP image. .SH OPTIONS The basic options are: .TP .BI \-o " string Specify the name of the output WebP file. If omitted, \fBgif2webp\fP will perform conversion but only report statistics. .TP .B \-h, \-help Usage information. .TP .B \-version Print the version number (as major.minor.revision) and exit. .TP .B \-lossy Encode the image using lossy compression. .TP .B \-mixed Mixed compression mode: optimize compression of the image by picking either lossy or lossless compression for each frame heuristically. .TP .BI \-q " float Specify the compression factor for RGB channels between 0 and 100. The default is 75. .br In case of lossless compression (default), a small factor enables faster compression speed, but produces a larger file. Maximum compression is achieved by using a value of 100. .br In case of lossy compression (specified by the \-lossy option), a small factor produces a smaller file with lower quality. Best quality is achieved by using a value of 100. .TP .BI \-m " int Specify the compression method to use. This parameter controls the trade off between encoding speed and the compressed file size and quality. Possible values range from 0 to 6. Default value is 4. When higher values are used, the encoder will spend more time inspecting additional encoding possibilities and decide on the quality gain. Lower value can result is faster processing time at the expense of larger file size and lower compression quality. .TP .BI \-kmin " int .TP .BI \-kmax " int Specify the minimum and maximum distance between consecutive key frames (independently decodable frames) in the output animation. The tool will insert some key frames into the output animation as needed so that this criteria is satisfied. .br A 'kmin' value of 0 will turn off insertion of key frames. Typical values are in the range 3 to 30. Default values are kmin = 9, kmax = 17 for lossless compression and kmin = 3, kmax = 5 for lossy compression. .br These two options are relevant only for animated images with large number of frames (>50). .br When lower values are used, more frames will be converted to key frames. This may lead to smaller number of frames required to decode a frame on average, thereby improving the decoding performance. But this may lead to slightly bigger file sizes. Higher values may lead to worse decoding performance, but smaller file sizes. .br Some restrictions: .br (i) kmin < kmax, .br (ii) kmin >= kmax / 2 + 1 and .br (iii) kmax - kmin <= 30. .br If any of these restrictions are not met, they will be enforced automatically. .TP .BI \-metadata " string A comma separated list of metadata to copy from the input to the output if present. Valid values: \fBall\fP, \fBnone\fP, \fBicc\fP, \fBxmp\fP. The default is \fBxmp\fP. .TP .BI \-f " int For lossy encoding only (specified by the \-lossy option). Specify the strength of the deblocking filter, between 0 (no filtering) and 100 (maximum filtering). A value of 0 will turn off any filtering. Higher value will increase the strength of the filtering process applied after decoding the picture. The higher the value the smoother the picture will appear. Typical values are usually in the range of 20 to 50. .TP .B \-mt Use multi-threading for encoding, if possible. This option is only effective when using lossy compression. .TP .B \-v Print extra information. .TP .B \-quiet Do not print anything. .SH BUGS Please report all bugs to our issue tracker: http://code.google.com/p/webp/issues .br Patches welcome! See this page to get started: http://www.webmproject.org/code/contribute/submitting-patches/ .SH EXAMPLES gif2webp picture.gif \-o picture.webp .br gif2webp \-q 70 picture.gif \-o picture.webp .br gif2webp \-lossy \-m 3 picture.gif \-o picture_lossy.webp .br gif2webp \-lossy \-f 50 picture.gif \-o picture.webp .br gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif .SH AUTHORS \fBgif2webp\fP was written by the WebP team. .br The latest source tree is available at http://www.webmproject.org/code .PP This manual page was written by Urvang Joshi , for the Debian project (and may be used by others). .SH SEE ALSO .BR cwebp (1), .BR dwebp (1), .BR webpmux (1) .br Please refer to http://developers.google.com/speed/webp/ for additional information. libwebp-0.4.0/man/Makefile.am0000644000014400001440000000021712255002107012650 0ustar man_MANS = cwebp.1 dwebp.1 if WANT_MUX man_MANS += webpmux.1 endif if BUILD_GIF2WEBP man_MANS += gif2webp.1 endif EXTRA_DIST = $(man_MANS) libwebp-0.4.0/missing0000755000014400001440000002415212255206714011456 0ustar #! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2012-01-06.13; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libwebp-0.4.0/Makefile.vc0000644000014400001440000002520012255002107012107 0ustar # # Stem for static libs and DLLs # LIBWEBPDECODER_BASENAME = libwebpdecoder LIBWEBP_BASENAME = libwebp LIBWEBPMUX_BASENAME = libwebpmux LIBWEBPDEMUX_BASENAME = libwebpdemux !IFNDEF ARCH !IF ! [ cl 2>&1 | find "x86" > NUL ] ARCH = x86 !ELSE IF ! [ cl 2>&1 | find "x64" > NUL ] ARCH = x64 !ELSE !ERROR Unable to auto-detect toolchain architecture! \ If cl.exe is in your PATH rerun nmake with ARCH=. !ENDIF !ENDIF !IF "$(ARCH)" == "x86" PLATFORM_LDFLAGS = /SAFESEH !ENDIF ############################################################# ## Nothing more to do below this line! NOLOGO = /nologo CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1 CFLAGS = /Isrc $(NOLOGO) /W3 /EHsc /c /GS CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN CFLAGS = $(CFLAGS) /DHAVE_WINCODEC_H /DWEBP_USE_THREAD LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS) LNKDLL = link.exe /DLL $(NOLOGO) LNKEXE = link.exe $(NOLOGO) LNKLIB = lib.exe $(NOLOGO) MT = mt.exe $(NOLOGO) CFGSET = FALSE !IF "$(OBJDIR)" == "" OUTDIR = ..\obj\ !ELSE OUTDIR = $(OBJDIR) !ENDIF ############################################################## # Runtime library configuration !IF "$(RTLIBCFG)" == "static" RTLIB = /MT RTLIBD = /MTd !ELSE RTLIB = /MD RTLIBD = /MDd !ENDIF DIRBASE = $(OUTDIR)\$(CFG)\$(ARCH) DIROBJ = $(DIRBASE)\obj DIRLIB = $(DIRBASE)\lib DIRINC = $(DIRBASE)\include DIRBIN = $(DIRBASE)\bin LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME).pdb OUTPUT_DIRS = $(DIRBIN) $(DIRINC) $(DIRLIB) \ $(DIROBJ)\dec \ $(DIROBJ)\demux \ $(DIROBJ)\dsp \ $(DIROBJ)\enc \ $(DIROBJ)\examples \ $(DIROBJ)\mux \ $(DIROBJ)\utils \ # Target configuration !IF "$(CFG)" == "release-static" CC = $(CCNODBG) STATICLIBBUILD = TRUE !ELSE IF "$(CFG)" == "debug-static" CC = $(CCDEBUG) RTLIB = $(RTLIBD) STATICLIBBUILD = TRUE LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug !ELSE IF "$(CFG)" == "release-dynamic" CC = $(CCNODBG) DLLBUILD = TRUE !ELSE IF "$(CFG)" == "debug-dynamic" CC = $(CCDEBUG) RTLIB = $(RTLIBD) DLLBUILD = TRUE LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug !ENDIF !IF "$(STATICLIBBUILD)" == "TRUE" CC = $(CC) $(RTLIB) CFGSET = TRUE LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME).lib LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME).lib LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib !ELSE IF "$(DLLBUILD)" == "TRUE" DLLC = webp_dll.c DLLINC = webp_dll.h DLL_OBJS = $(DIROBJ)\$(DLLC:.c=.obj) 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 LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME)_dll.lib LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb CFGSET = TRUE !ENDIF ####################### # Usage # !IF "$(CFGSET)" == "FALSE" !MESSAGE Usage: nmake /f Makefile.vc [CFG=] !MESSAGE . [OBJDIR=] [RTLIBCFG=] [] !MESSAGE !MESSAGE where is one of: !MESSAGE - release-static - release static library !MESSAGE - debug-static - debug static library !MESSAGE - release-dynamic - release dynamic link library (DLL) !MESSAGE - debug-dynamic - debug dynamic link library (DLL) !MESSAGE !MESSAGE may be: !MESSAGE - clean - perform a clean for CFG !MESSAGE - experimental - build CFG with experimental !MESSAGE . features enabled. !MESSAGE - (empty) - build libwebp-based targets for CFG !MESSAGE - all - build (de)mux-based targets for CFG !MESSAGE !MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'. !MESSAGE OBJDIR is the path where you like to build (obj, bins, etc.), !MESSAGE defaults to ..\obj !IF "$(CFG)" != "" !MESSAGE !ERROR please choose a valid configuration instead of "$(CFG)" !ENDIF !ENDIF ####################### # Rules # !IF "$(CFGSET)" == "TRUE" # A config was provided, so the library can be built. # DEC_OBJS = \ $(DIROBJ)\dec\alpha.obj \ $(DIROBJ)\dec\buffer.obj \ $(DIROBJ)\dec\frame.obj \ $(DIROBJ)\dec\idec.obj \ $(DIROBJ)\dec\io.obj \ $(DIROBJ)\dec\layer.obj \ $(DIROBJ)\dec\quant.obj \ $(DIROBJ)\dec\tree.obj \ $(DIROBJ)\dec\vp8.obj \ $(DIROBJ)\dec\vp8l.obj \ $(DIROBJ)\dec\webp.obj \ DEMUX_OBJS = \ $(DIROBJ)\demux\demux.obj \ DSP_DEC_OBJS = \ $(DIROBJ)\dsp\cpu.obj \ $(DIROBJ)\dsp\dec.obj \ $(DIROBJ)\dsp\dec_neon.obj \ $(DIROBJ)\dsp\dec_sse2.obj \ $(DIROBJ)\dsp\lossless.obj \ $(DIROBJ)\dsp\upsampling.obj \ $(DIROBJ)\dsp\upsampling_neon.obj \ $(DIROBJ)\dsp\upsampling_sse2.obj \ $(DIROBJ)\dsp\yuv.obj \ DSP_ENC_OBJS = \ $(DIROBJ)\dsp\enc.obj \ $(DIROBJ)\dsp\enc_neon.obj \ $(DIROBJ)\dsp\enc_sse2.obj \ EX_FORMAT_DEC_OBJS = \ $(DIROBJ)\examples\jpegdec.obj \ $(DIROBJ)\examples\metadata.obj \ $(DIROBJ)\examples\pngdec.obj \ $(DIROBJ)\examples\tiffdec.obj \ $(DIROBJ)\examples\wicdec.obj \ EX_UTIL_OBJS = \ $(DIROBJ)\examples\example_util.obj \ ENC_OBJS = \ $(DIROBJ)\enc\alpha.obj \ $(DIROBJ)\enc\analysis.obj \ $(DIROBJ)\enc\backward_references.obj \ $(DIROBJ)\enc\config.obj \ $(DIROBJ)\enc\cost.obj \ $(DIROBJ)\enc\filter.obj \ $(DIROBJ)\enc\frame.obj \ $(DIROBJ)\enc\histogram.obj \ $(DIROBJ)\enc\iterator.obj \ $(DIROBJ)\enc\layer.obj \ $(DIROBJ)\enc\picture.obj \ $(DIROBJ)\enc\quant.obj \ $(DIROBJ)\enc\syntax.obj \ $(DIROBJ)\enc\token.obj \ $(DIROBJ)\enc\tree.obj \ $(DIROBJ)\enc\vp8l.obj \ $(DIROBJ)\enc\webpenc.obj \ MUX_OBJS = \ $(DIROBJ)\mux\muxedit.obj \ $(DIROBJ)\mux\muxinternal.obj \ $(DIROBJ)\mux\muxread.obj \ UTILS_DEC_OBJS = \ $(DIROBJ)\utils\alpha_processing.obj \ $(DIROBJ)\utils\bit_reader.obj \ $(DIROBJ)\utils\color_cache.obj \ $(DIROBJ)\utils\filters.obj \ $(DIROBJ)\utils\huffman.obj \ $(DIROBJ)\utils\quant_levels_dec.obj \ $(DIROBJ)\utils\rescaler.obj \ $(DIROBJ)\utils\random.obj \ $(DIROBJ)\utils\thread.obj \ $(DIROBJ)\utils\utils.obj \ UTILS_ENC_OBJS = \ $(DIROBJ)\utils\bit_writer.obj \ $(DIROBJ)\utils\huffman_encode.obj \ $(DIROBJ)\utils\quant_levels.obj \ LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS) LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \ $(UTILS_ENC_OBJS) $(DLL_OBJS) LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS) LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS) OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP) OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe ex: $(OUT_LIBS) $(OUT_EXAMPLES) all: ex $(EXTRA_EXAMPLES) $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(EX_FORMAT_DEC_OBJS) $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(DIRBIN)\vwebp.exe: $(EX_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) $(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX) $(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(LIBWEBP) $(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP) $(EX_UTIL_OBJS) $(EX_FORMAT_DEC_OBJS): $(OUTPUT_DIRS) experimental: $(MAKE) /f Makefile.vc \ CFG=$(CFG) \ CFLAGS="$(CFLAGS) /DWEBP_EXPERIMENTAL_FEATURES" /$(MAKEFLAGS) $(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS) $(LIBWEBP): $(LIBWEBP_OBJS) $(LIBWEBPMUX): $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX): $(LIBWEBPDEMUX_OBJS) $(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): $(OUTPUT_DIRS) !IF "$(DLLBUILD)" == "TRUE" $(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): \ $(DIROBJ)\$(DLLINC) $(DIROBJ)\$(DLLC) {$(DIROBJ)}.c{$(DIROBJ)}.obj: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@ $< $(LIBWEBPMUX): $(LIBWEBP) $(LIBWEBPDEMUX): $(LIBWEBP) $(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX): $(LNKDLL) /out:$(DIRBIN)\$(@B:_dll=.dll) /implib:$@ $(LFLAGS) $** -xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y clean:: @-erase /s $(DIROBJ)\$(DLLC) $(DIROBJ)\$(DLLINC) 2> NUL !ELSE $(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX): $(LNKLIB) /out:$@ $** -xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y !ENDIF $(OUTPUT_DIRS): @if not exist "$(@)" mkdir "$(@)" # generate a helper include to define WEBP_EXTERN suitable for the DLL build $(DIROBJ)\$(DLLINC): @echo #ifndef WEBP_DLL_H_ > $@ @echo #define WEBP_DLL_H_ >> $@ @echo #define WEBP_EXTERN(type) __declspec(dllexport) type >> $@ @echo #endif /* WEBP_DLL_H_ */ >> $@ # expose a WebPFree() function for use in managed code $(DIROBJ)\$(DLLC): $(DIROBJ)\$(DLLINC) @echo #include ^ > $@ @echo #include "webp_dll.h" >> $@ @echo // This function should be used in place of free() for memory >> $@ @echo // returned by the WebP API. >> $@ @echo WEBP_EXTERN(void) WebPFree(void* ptr) { >> $@ @echo free(ptr); >> $@ @echo } >> $@ .SUFFIXES: .c .obj .res .exe {examples}.c{$(DIROBJ)\examples}.obj:: $(CC) $(CFLAGS) /Fd$(DIROBJ)\examples\ /Fo$(DIROBJ)\examples\ $< {src\dec}.c{$(DIROBJ)\dec}.obj:: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $< {src\demux}.c{$(DIROBJ)\demux}.obj:: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\demux\ $< {src\dsp}.c{$(DIROBJ)\dsp}.obj:: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ $< {src\enc}.c{$(DIROBJ)\enc}.obj:: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\enc\ $< {src\mux}.c{$(DIROBJ)\mux}.obj:: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\mux\ $< {src\utils}.c{$(DIROBJ)\utils}.obj:: $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $< {$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe: $(LNKEXE) $(LDFLAGS) /OUT:$@ $** \ ole32.lib windowscodecs.lib shlwapi.lib $(MT) -manifest $@.manifest -outputresource:$@;1 del $@.manifest clean:: @-erase /s $(DIROBJ)\*.dll 2> NUL @-erase /s $(DIROBJ)\*.exp 2> NUL @-erase /s $(DIROBJ)\*.idb 2> NUL @-erase /s $(DIROBJ)\*.lib 2> NUL @-erase /s $(DIROBJ)\*.obj 2> NUL @-erase /s $(DIROBJ)\*.pch 2> NUL @-erase /s $(DIROBJ)\*.pdb 2> NUL @-erase /s $(DIROBJ)\*.res 2> NUL !ENDIF # End of case where a config was provided. libwebp-0.4.0/swig/0000755000014400001440000000000012255002107011012 5ustar libwebp-0.4.0/swig/libwebp_go_wrap.c0000644000014400001440000001456612255002107014334 0ustar /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). * Version 2.0.10 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make * changes to this file unless you know what you are doing--modify the SWIG * interface file instead. * ----------------------------------------------------------------------------- */ #define SWIGMODULE libwebp /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. * ----------------------------------------------------------------------------- */ /* template workaround for compilers that cannot correctly implement the C++ standard */ #ifndef SWIGTEMPLATEDISAMBIGUATOR # if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) # define SWIGTEMPLATEDISAMBIGUATOR template # elif defined(__HP_aCC) /* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ /* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ # define SWIGTEMPLATEDISAMBIGUATOR template # else # define SWIGTEMPLATEDISAMBIGUATOR # endif #endif /* inline attribute */ #ifndef SWIGINLINE # if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) # define SWIGINLINE inline # else # define SWIGINLINE # endif #endif /* attribute recognised by some compilers to avoid 'unused' warnings */ #ifndef SWIGUNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define SWIGUNUSED __attribute__ ((__unused__)) # else # define SWIGUNUSED # endif # elif defined(__ICC) # define SWIGUNUSED __attribute__ ((__unused__)) # else # define SWIGUNUSED # endif #endif #ifndef SWIG_MSC_UNSUPPRESS_4505 # if defined(_MSC_VER) # pragma warning(disable : 4505) /* unreferenced local function has been removed */ # endif #endif #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) # else # define SWIGUNUSEDPARM(p) p SWIGUNUSED # endif #endif /* internal SWIG method */ #ifndef SWIGINTERN # define SWIGINTERN static SWIGUNUSED #endif /* internal inline SWIG method */ #ifndef SWIGINTERNINLINE # define SWIGINTERNINLINE SWIGINTERN SWIGINLINE #endif /* exporting methods */ #if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) # ifndef GCC_HASCLASSVISIBILITY # define GCC_HASCLASSVISIBILITY # endif #endif #ifndef SWIGEXPORT # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # if defined(STATIC_LINKED) # define SWIGEXPORT # else # define SWIGEXPORT __declspec(dllexport) # endif # else # if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) # define SWIGEXPORT __attribute__ ((visibility("default"))) # else # define SWIGEXPORT # endif # endif #endif /* calling conventions for Windows */ #ifndef SWIGSTDCALL # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # define SWIGSTDCALL __stdcall # else # define SWIGSTDCALL # endif #endif /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) # define _CRT_SECURE_NO_DEPRECATE #endif /* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ #if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) # define _SCL_SECURE_NO_DEPRECATE #endif #include #include #include #include #include typedef long long intgo; typedef unsigned long long uintgo; typedef struct { char *p; intgo n; } _gostring_; typedef struct { void* array; intgo len; intgo cap; } _goslice_; #define swiggo_size_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2+1]; #define swiggo_size_assert(t, n) swiggo_size_assert_eq(sizeof(t), n, swiggo_sizeof_##t##_is_not_##n) swiggo_size_assert(char, 1) swiggo_size_assert(short, 2) swiggo_size_assert(int, 4) typedef long long swiggo_long_long; swiggo_size_assert(swiggo_long_long, 8) swiggo_size_assert(float, 4) swiggo_size_assert(double, 8) #ifdef __cplusplus extern "C" { #endif extern void crosscall2(void (*fn)(void *, int), void *, int); extern void _cgo_allocate(void *, int); extern void _cgo_panic(void *, int); #ifdef __cplusplus } #endif static void *_swig_goallocate(size_t len) { struct { size_t len; void *ret; } a; a.len = len; crosscall2(_cgo_allocate, &a, (int) sizeof a); return a.ret; } static void _swig_gopanic(const char *p) { struct { const char *p; } a; a.p = p; crosscall2(_cgo_panic, &a, (int) sizeof a); } static _gostring_ _swig_makegostring(const char *p, size_t l) { _gostring_ ret; ret.p = (char*)_swig_goallocate(l + 1); memcpy(ret.p, p, l); ret.n = l; return ret; } #define SWIG_contract_assert(expr, msg) \ if (!(expr)) { _swig_gopanic(msg); } else #define SWIG_exception(code, msg) _swig_gopanic(msg) #include "webp/decode.h" #include "webp/encode.h" #ifdef __cplusplus extern "C" { #endif void _wrap_WebPGetDecoderVersion(void *swig_v) { int result; struct swigargs { long : 0; intgo result; } *swig_a = (struct swigargs *) swig_v; result = (int)WebPGetDecoderVersion(); swig_a->result = result; } void _wrap_wrapped_WebPGetInfo(void *swig_v) { uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int temp3 ; int temp4 ; int result; struct swigargs { _gostring_ arg1; _goslice_ arg3; _goslice_ arg4; long : 0; intgo result; } *swig_a = (struct swigargs *) swig_v; arg1 = (uint8_t *)swig_a->arg1.p; arg2 = (size_t)swig_a->arg1.n; { if (swig_a->arg3.len == 0) { _swig_gopanic("array must contain at least 1 element"); } arg3 = &temp3; } { if (swig_a->arg4.len == 0) { _swig_gopanic("array must contain at least 1 element"); } arg4 = &temp4; } result = (int)WebPGetInfo((uint8_t const *)arg1,arg2,arg3,arg4); swig_a->result = result; { int* a = (int *) swig_a->arg3.array; a[0] = temp3; } { int* a = (int *) swig_a->arg4.array; a[0] = temp4; } } #ifdef __cplusplus } #endif libwebp-0.4.0/swig/README0000644000014400001440000000305212255002107011672 0ustar Building: ========= JNI SWIG bindings: ------------------ $ gcc -shared -fPIC -fno-strict-aliasing -O2 \ -I/path/to/your/jdk/includes \ libwebp_java_wrap.c \ -lwebp \ -o libwebp_jni.so -------------------------------------- BEGIN PSEUDO EXAMPLE import com.google.webp.libwebp; import java.lang.reflect.Method; public class libwebp_jni_example { static { System.loadLibrary("webp_jni"); } /** * usage: java -cp libwebp.jar:. libwebp_jni_example */ public static void main(String argv[]) { final int version = libwebp.WebPGetDecoderVersion(); System.out.println("libwebp version: " + Integer.toHexString(version)); System.out.println("libwebp methods:"); final Method[] libwebpMethods = libwebp.class.getDeclaredMethods(); for (int i = 0; i < libwebpMethods.length; i++) { System.out.println(libwebpMethods[i]); } } } -------------------------------------- END PSEUDO EXAMPLE $ javac -cp libwebp.jar libwebp_jni_example.java $ java -Djava.library.path=. -cp libwebp.jar:. libwebp_jni_example Python SWIG bindings: --------------------- $ python setup.py build_ext $ python setup.py install --prefix=pylocal -------------------------------------- BEGIN PSEUDO EXAMPLE import glob import sys sys.path.append(glob.glob('pylocal/lib/python*/site-packages')[0]) from com.google.webp import libwebp print "libwebp decoder version: %x" % libwebp.WebPGetDecoderVersion() print "libwebp attributes:" for attr in dir(libwebp): print attr -------------------------------------- END PSEUDO EXAMPLE libwebp-0.4.0/swig/libwebp.swig0000644000014400001440000003372712255002107013345 0ustar // Copyright 2011 Google Inc. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // libwebp swig interface definition // // Author: James Zern (jzern@google.com) /* Go bindings: $ swig -go \ -outdir . \ -o libwebp_go_wrap.c libwebp.swig Java bindings: $ mkdir -p java/com/google/webp $ swig -java \ -package com.google.webp \ -outdir java/com/google/webp \ -o libwebp_java_wrap.c libwebp.swig Python bindings: $ swig -python \ -outdir . \ -o libwebp_python_wrap.c libwebp.swig */ #ifdef SWIGPYTHON %module(package="com.google.webp") libwebp #else %module libwebp #endif /* SWIGPYTHON */ %include "constraints.i" %include "typemaps.i" #ifdef SWIGGO %apply (char* STRING, size_t LENGTH) { (const uint8_t* data, size_t data_size) } %rename(wrapped_WebPGetInfo) WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); #endif /* SWIGGO */ #ifdef SWIGJAVA %include "arrays_java.i"; %include "enums.swg" /*NB: requires JDK-1.5+ See: http://www.swig.org/Doc1.3/Java.html#enumerations */ // map uint8_t* such that a byte[] is used %{ #include "webp/types.h" %} // from arrays_java.i (signed char) JAVA_ARRAYS_DECL(uint8_t, jbyte, Byte, Uint8) JAVA_ARRAYS_IMPL(uint8_t, jbyte, Byte, Uint8) JAVA_ARRAYS_TYPEMAPS(uint8_t, byte, jbyte, Uint8, "[B") %apply uint8_t[] { uint8_t* } #endif /* SWIGJAVA */ #ifdef SWIGPYTHON %apply (char* STRING, size_t LENGTH) { (const uint8_t* data, size_t data_size) } %typemap(out) uint8_t* { $result = PyString_FromStringAndSize( (const char*)$1, ($1 == NULL) ? 0 : ReturnedBufferSize("$symname", arg3, arg4)); } %typemap (in) const uint8_t* rgb (Py_buffer rgb_buffer) { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer($input, (const void**)(&$1), &unused); if (!PyObject_CheckBuffer($input)) { SWIG_exception_fail(SWIG_TypeError, "in method '$symname', argument $argnum" " does not support the buffer interface"); } if (PyObject_GetBuffer($input, &rgb_buffer, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method '$symname', unable to get buffer view"); } $1 = ($1_ltype)rgb_buffer.buf; } %typemap(freearg) const uint8_t* rgb { PyBuffer_Release(&rgb_buffer$argnum); } %define DECODE_AUTODOC(func) %feature("autodoc", #func "(uint8_t data) -> (rgb, width, height)") func; %enddef %feature("autodoc", "1"); DECODE_AUTODOC(WebPDecodeRGB); DECODE_AUTODOC(WebPDecodeRGBA); DECODE_AUTODOC(WebPDecodeARGB); DECODE_AUTODOC(WebPDecodeBGR); DECODE_AUTODOC(WebPDecodeBGRA); %feature("autodoc", "WebPGetInfo(uint8_t data) -> (width, height)") WebPGetInfo; #endif /* SWIGPYTHON */ //------------------------------------------------------------------------------ // Decoder specific %apply int* OUTPUT { int* width, int* height } int WebPGetDecoderVersion(void); int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); #if defined(SWIGJAVA) || defined(SWIGPYTHON) // free the buffer returned by these functions after copying into // the native type %newobject WebPDecodeRGB; %newobject WebPDecodeRGBA; %newobject WebPDecodeARGB; %newobject WebPDecodeBGR; %newobject WebPDecodeBGRA; %typemap(newfree) uint8_t* "free($1);" uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height); uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, int* width, int* height); uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, int* width, int* height); uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, int* width, int* height); uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, int* width, int* height); #endif /* SWIGJAVA || SWIGPYTHON */ //------------------------------------------------------------------------------ // Encoder specific #if defined(SWIGJAVA) || defined(SWIGPYTHON) int WebPGetEncoderVersion(void); #endif /* SWIGJAVA || SWIGPYTHON */ //------------------------------------------------------------------------------ // Wrapper code additions %{ #include "webp/decode.h" #include "webp/encode.h" %} #ifdef SWIGJAVA %{ #define FillMeInAsSizeCannotBeDeterminedAutomatically \ (result ? (jint)ReturnedBufferSize(__FUNCTION__, arg3, arg4) : 0) %} #endif /* SWIGJAVA */ #if defined(SWIGJAVA) || defined(SWIGPYTHON) %{ static size_t ReturnedBufferSize( const char* function, int* width, int* height) { static const struct sizemap { const char* function; int size_multiplier; } size_map[] = { #ifdef SWIGJAVA { "Java_com_google_webp_libwebpJNI_WebPDecodeRGB", 3 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeRGBA", 4 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeARGB", 4 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeBGR", 3 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeBGRA", 4 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGB", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGR", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGBA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGRA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGB", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGR", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGBA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGRA", 1 }, #endif #ifdef SWIGPYTHON { "WebPDecodeRGB", 3 }, { "WebPDecodeRGBA", 4 }, { "WebPDecodeARGB", 4 }, { "WebPDecodeBGR", 3 }, { "WebPDecodeBGRA", 4 }, { "wrap_WebPEncodeRGB", 1 }, { "wrap_WebPEncodeBGR", 1 }, { "wrap_WebPEncodeRGBA", 1 }, { "wrap_WebPEncodeBGRA", 1 }, { "wrap_WebPEncodeLosslessRGB", 1 }, { "wrap_WebPEncodeLosslessBGR", 1 }, { "wrap_WebPEncodeLosslessRGBA", 1 }, { "wrap_WebPEncodeLosslessBGRA", 1 }, #endif { NULL, 0 } }; const struct sizemap* p; size_t size = 0; for (p = size_map; p->function; ++p) { if (!strcmp(function, p->function)) { size = *width * *height * p->size_multiplier; break; } } return size; } %} %{ typedef size_t (*WebPEncodeFunction)(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); typedef size_t (*WebPEncodeLosslessFunction)(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); static uint8_t* EncodeLossy(const uint8_t* rgb, int width, int height, int stride, float quality_factor, WebPEncodeFunction encfn, int* output_size, int* unused) { uint8_t* output = NULL; const size_t image_size = encfn(rgb, width, height, stride, quality_factor, &output); // the values of following two will be interpreted by ReturnedBufferSize() // as 'width' and 'height' in the size calculation. *output_size = image_size; *unused = 1; return image_size ? output : NULL; } static uint8_t* EncodeLossless(const uint8_t* rgb, int width, int height, int stride, WebPEncodeLosslessFunction encfn, int* output_size, int* unused) { uint8_t* output = NULL; const size_t image_size = encfn(rgb, width, height, stride, &output); // the values of the following two will be interpreted by // ReturnedBufferSize() as 'width' and 'height' in the size calculation. *output_size = image_size; *unused = 1; return image_size ? output : NULL; } %} #endif /* SWIGJAVA || SWIGPYTHON */ //------------------------------------------------------------------------------ // libwebp/encode wrapper functions #if defined(SWIGJAVA) || defined(SWIGPYTHON) %apply int* INPUT { int* unused1, int* unused2 } %apply int* OUTPUT { int* output_size } // free the buffer returned by these functions after copying into // the native type %newobject wrap_WebPEncodeRGB; %newobject wrap_WebPEncodeBGR; %newobject wrap_WebPEncodeRGBA; %newobject wrap_WebPEncodeBGRA; %newobject wrap_WebPEncodeLosslessRGB; %newobject wrap_WebPEncodeLosslessBGR; %newobject wrap_WebPEncodeLosslessRGBA; %newobject wrap_WebPEncodeLosslessBGRA; #ifdef SWIGJAVA // There's no reason to call these directly %javamethodmodifiers wrap_WebPEncodeRGB "private"; %javamethodmodifiers wrap_WebPEncodeBGR "private"; %javamethodmodifiers wrap_WebPEncodeRGBA "private"; %javamethodmodifiers wrap_WebPEncodeBGRA "private"; %javamethodmodifiers wrap_WebPEncodeLosslessRGB "private"; %javamethodmodifiers wrap_WebPEncodeLosslessBGR "private"; %javamethodmodifiers wrap_WebPEncodeLosslessRGBA "private"; %javamethodmodifiers wrap_WebPEncodeLosslessBGRA "private"; #endif /* SWIGJAVA */ #ifdef SWIGPYTHON // This autodoc will serve as a catch-all for wrap_*. %feature("autodoc", "private, do not call directly."); #endif %inline %{ // Changes the return type of WebPEncode* to more closely match Decode*. // This also makes it easier to wrap the output buffer in a native type rather // than dealing with the return pointer. // The additional parameters are to allow reuse of ReturnedBufferSize(), // unused2 and output_size will be used in this case. #define LOSSY_WRAPPER(FUNC) \ static uint8_t* wrap_##FUNC( \ const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ int width, int height, int stride, float quality_factor) { \ return EncodeLossy(rgb, width, height, stride, quality_factor, \ FUNC, output_size, unused2); \ } \ LOSSY_WRAPPER(WebPEncodeRGB) LOSSY_WRAPPER(WebPEncodeBGR) LOSSY_WRAPPER(WebPEncodeRGBA) LOSSY_WRAPPER(WebPEncodeBGRA) #undef LOSSY_WRAPPER #define LOSSLESS_WRAPPER(FUNC) \ static uint8_t* wrap_##FUNC( \ const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ int width, int height, int stride) { \ return EncodeLossless(rgb, width, height, stride, \ FUNC, output_size, unused2); \ } \ LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) #undef LOSSLESS_WRAPPER %} #endif /* SWIGJAVA || SWIGPYTHON */ //------------------------------------------------------------------------------ // Language specific #ifdef SWIGGO %insert(go_wrapper) %{ // WebPGetInfo has 2 output parameters, provide a version in the more natural // go idiom: func WebPGetInfo(webp []byte) (ok bool, width int, height int) { w := []int{0} h := []int{0} ok = Wrapped_WebPGetInfo(string(webp), w, h) != 0 width = w[0] height = h[0] return } %} #endif /* SWIGGO */ #ifdef SWIGJAVA %{ /* Work around broken gcj jni.h */ #ifdef __GCJ_JNI_H__ # undef JNIEXPORT # define JNIEXPORT # undef JNICALL # define JNICALL #endif %} %pragma(java) modulecode=%{ private static final int UNUSED = 1; private static int outputSize[] = { 0 }; %} %define CALL_ENCODE_LOSSY_WRAPPER(func) %pragma(java) modulecode=%{ public static byte[] func( byte[] rgb, int width, int height, int stride, float quality_factor) { return wrap_##func( rgb, UNUSED, UNUSED, outputSize, width, height, stride, quality_factor); } %} %enddef %define CALL_ENCODE_LOSSLESS_WRAPPER(func) %pragma(java) modulecode=%{ public static byte[] func( byte[] rgb, int width, int height, int stride) { return wrap_##func( rgb, UNUSED, UNUSED, outputSize, width, height, stride); } %} %enddef CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGB) CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGBA) CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGR) CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGRA) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) #endif /* SWIGJAVA */ #ifdef SWIGPYTHON %pythoncode %{ _UNUSED = 1 %} %define CALL_ENCODE_LOSSY_WRAPPER(func) %pythoncode %{ def func(rgb, width, height, stride, quality_factor): """func(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" webp = wrap_##func( rgb, _UNUSED, _UNUSED, width, height, stride, quality_factor) if len(webp[0]) == 0: return None return webp[0] %} %enddef %define CALL_ENCODE_LOSSLESS_WRAPPER(func) %pythoncode %{ def func(rgb, width, height, stride): """func(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" webp = wrap_##func(rgb, _UNUSED, _UNUSED, width, height, stride) if len(webp[0]) == 0: return None return webp[0] %} %enddef CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGB) CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGBA) CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGR) CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGRA) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) #endif /* SWIGPYTHON */ libwebp-0.4.0/swig/libwebp_python_wrap.c0000644000014400001440000050603312255002107015243 0ustar /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). * Version 2.0.4 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make * changes to this file unless you know what you are doing--modify the SWIG * interface file instead. * ----------------------------------------------------------------------------- */ #define SWIGPYTHON #define SWIG_PYTHON_DIRECTOR_NO_VTABLE /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. * ----------------------------------------------------------------------------- */ /* template workaround for compilers that cannot correctly implement the C++ standard */ #ifndef SWIGTEMPLATEDISAMBIGUATOR # if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) # define SWIGTEMPLATEDISAMBIGUATOR template # elif defined(__HP_aCC) /* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ /* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ # define SWIGTEMPLATEDISAMBIGUATOR template # else # define SWIGTEMPLATEDISAMBIGUATOR # endif #endif /* inline attribute */ #ifndef SWIGINLINE # if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) # define SWIGINLINE inline # else # define SWIGINLINE # endif #endif /* attribute recognised by some compilers to avoid 'unused' warnings */ #ifndef SWIGUNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define SWIGUNUSED __attribute__ ((__unused__)) # else # define SWIGUNUSED # endif # elif defined(__ICC) # define SWIGUNUSED __attribute__ ((__unused__)) # else # define SWIGUNUSED # endif #endif #ifndef SWIG_MSC_UNSUPPRESS_4505 # if defined(_MSC_VER) # pragma warning(disable : 4505) /* unreferenced local function has been removed */ # endif #endif #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) # else # define SWIGUNUSEDPARM(p) p SWIGUNUSED # endif #endif /* internal SWIG method */ #ifndef SWIGINTERN # define SWIGINTERN static SWIGUNUSED #endif /* internal inline SWIG method */ #ifndef SWIGINTERNINLINE # define SWIGINTERNINLINE SWIGINTERN SWIGINLINE #endif /* exporting methods */ #if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) # ifndef GCC_HASCLASSVISIBILITY # define GCC_HASCLASSVISIBILITY # endif #endif #ifndef SWIGEXPORT # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # if defined(STATIC_LINKED) # define SWIGEXPORT # else # define SWIGEXPORT __declspec(dllexport) # endif # else # if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) # define SWIGEXPORT __attribute__ ((visibility("default"))) # else # define SWIGEXPORT # endif # endif #endif /* calling conventions for Windows */ #ifndef SWIGSTDCALL # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # define SWIGSTDCALL __stdcall # else # define SWIGSTDCALL # endif #endif /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) # define _CRT_SECURE_NO_DEPRECATE #endif /* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ #if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) # define _SCL_SECURE_NO_DEPRECATE #endif /* Python.h has to appear first */ #include /* ----------------------------------------------------------------------------- * swigrun.swg * * This file contains generic C API SWIG runtime support for pointer * type checking. * ----------------------------------------------------------------------------- */ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ #define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE # define SWIG_QUOTE_STRING(x) #x # define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) # define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) #else # define SWIG_TYPE_TABLE_NAME #endif /* You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for creating a static or dynamic library from the SWIG runtime code. In 99.9% of the cases, SWIG just needs to declare them as 'static'. But only do this if strictly necessary, ie, if you have problems with your compiler or suchlike. */ #ifndef SWIGRUNTIME # define SWIGRUNTIME SWIGINTERN #endif #ifndef SWIGRUNTIMEINLINE # define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE #endif /* Generic buffer size */ #ifndef SWIG_BUFFER_SIZE # define SWIG_BUFFER_SIZE 1024 #endif /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 #define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 /* Flags/methods for returning states. The SWIG conversion methods, as ConvertPtr, return an integer that tells if the conversion was successful or not. And if not, an error code can be returned (see swigerrors.swg for the codes). Use the following macros/flags to set or process the returning states. In old versions of SWIG, code such as the following was usually written: if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { // success code } else { //fail code } Now you can be more explicit: int res = SWIG_ConvertPtr(obj,vptr,ty.flags); if (SWIG_IsOK(res)) { // success code } else { // fail code } which is the same really, but now you can also do Type *ptr; int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); if (SWIG_IsOK(res)) { // success code if (SWIG_IsNewObj(res) { ... delete *ptr; } else { ... } } else { // fail code } I.e., now SWIG_ConvertPtr can return new objects and you can identify the case and take care of the deallocation. Of course that also requires SWIG_ConvertPtr to return new result values, such as int SWIG_ConvertPtr(obj, ptr,...) { if () { if () { *ptr = ; return SWIG_NEWOBJ; } else { *ptr = ; return SWIG_OLDOBJ; } } else { return SWIG_BADOBJ; } } Of course, returning the plain '0(success)/-1(fail)' still works, but you can be more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the SWIG errors code. Finally, if the SWIG_CASTRANK_MODE is enabled, the result code allows to return the 'cast rank', for example, if you have this int food(double) int fooi(int); and you call food(1) // cast rank '1' (1 -> 1.0) fooi(1) // cast rank '0' just use the SWIG_AddCast()/SWIG_CheckState() */ #define SWIG_OK (0) #define SWIG_ERROR (-1) #define SWIG_IsOK(r) (r >= 0) #define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) /* The CastRankLimit says how many bits are used for the cast rank */ #define SWIG_CASTRANKLIMIT (1 << 8) /* The NewMask denotes the object was created (using new/malloc) */ #define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) /* The TmpMask is for in/out typemaps that use temporal objects */ #define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) /* Simple returning values */ #define SWIG_BADOBJ (SWIG_ERROR) #define SWIG_OLDOBJ (SWIG_OK) #define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) #define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) /* Check, add and del mask methods */ #define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) #define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) #define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) #define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) #define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) #define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) /* Cast-Rank Mode */ #if defined(SWIG_CASTRANK_MODE) # ifndef SWIG_TypeRank # define SWIG_TypeRank unsigned long # endif # ifndef SWIG_MAXCASTRANK /* Default cast allowed */ # define SWIG_MAXCASTRANK (2) # endif # define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) # define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) SWIGINTERNINLINE int SWIG_AddCast(int r) { return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; } SWIGINTERNINLINE int SWIG_CheckState(int r) { return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; } #else /* no cast-rank mode */ # define SWIG_AddCast # define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) #endif #include #ifdef __cplusplus extern "C" { #endif typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); /* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ struct swig_cast_info *cast; /* linked list of types that can cast into this type */ void *clientdata; /* language specific type data */ int owndata; /* flag if the structure owns the clientdata */ } swig_type_info; /* Structure to store a type and conversion function used for casting */ typedef struct swig_cast_info { swig_type_info *type; /* pointer to type that is equivalent to this type */ swig_converter_func converter; /* function to cast the void pointers */ struct swig_cast_info *next; /* pointer to next cast in linked list */ struct swig_cast_info *prev; /* pointer to the previous cast */ } swig_cast_info; /* Structure used to store module information * Each module generates one structure like this, and the runtime collects * all of these structures and stores them in a circularly linked list.*/ typedef struct swig_module_info { swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ size_t size; /* Number of types in this module */ struct swig_module_info *next; /* Pointer to next element in circularly linked list */ swig_type_info **type_initial; /* Array of initially generated type structures */ swig_cast_info **cast_initial; /* Array of initially generated casting structures */ void *clientdata; /* Language specific module data */ } swig_module_info; /* Compare two type names skipping the space characters, therefore "char*" == "char *" and "Class" == "Class", etc. Return 0 when the two name types are equivalent, as in strncmp, but skipping ' '. */ SWIGRUNTIME int SWIG_TypeNameComp(const char *f1, const char *l1, const char *f2, const char *l2) { for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { while ((*f1 == ' ') && (f1 != l1)) ++f1; while ((*f2 == ' ') && (f2 != l2)) ++f2; if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; } return (int)((l1 - f1) - (l2 - f2)); } /* Check type equivalence in a name list like ||... Return 0 if not equal, 1 if equal */ SWIGRUNTIME int SWIG_TypeEquiv(const char *nb, const char *tb) { int equiv = 0; const char* te = tb + strlen(tb); const char* ne = nb; while (!equiv && *ne) { for (nb = ne; *ne; ++ne) { if (*ne == '|') break; } equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; if (*ne) ++ne; } return equiv; } /* Check type equivalence in a name list like ||... Return 0 if equal, -1 if nb < tb, 1 if nb > tb */ SWIGRUNTIME int SWIG_TypeCompare(const char *nb, const char *tb) { int equiv = 0; const char* te = tb + strlen(tb); const char* ne = nb; while (!equiv && *ne) { for (nb = ne; *ne; ++ne) { if (*ne == '|') break; } equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; if (*ne) ++ne; } return equiv; } /* Check the typename */ SWIGRUNTIME swig_cast_info * SWIG_TypeCheck(const char *c, swig_type_info *ty) { if (ty) { swig_cast_info *iter = ty->cast; while (iter) { if (strcmp(iter->type->name, c) == 0) { if (iter == ty->cast) return iter; /* Move iter to the top of the linked list */ iter->prev->next = iter->next; if (iter->next) iter->next->prev = iter->prev; iter->next = ty->cast; iter->prev = 0; if (ty->cast) ty->cast->prev = iter; ty->cast = iter; return iter; } iter = iter->next; } } return 0; } /* Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison */ SWIGRUNTIME swig_cast_info * SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { if (ty) { swig_cast_info *iter = ty->cast; while (iter) { if (iter->type == from) { if (iter == ty->cast) return iter; /* Move iter to the top of the linked list */ iter->prev->next = iter->next; if (iter->next) iter->next->prev = iter->prev; iter->next = ty->cast; iter->prev = 0; if (ty->cast) ty->cast->prev = iter; ty->cast = iter; return iter; } iter = iter->next; } } return 0; } /* Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* Dynamic pointer casting. Down an inheritance hierarchy */ SWIGRUNTIME swig_type_info * SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { swig_type_info *lastty = ty; if (!ty || !ty->dcast) return ty; while (ty && (ty->dcast)) { ty = (*ty->dcast)(ptr); if (ty) lastty = ty; } return lastty; } /* Return the name associated with this type */ SWIGRUNTIMEINLINE const char * SWIG_TypeName(const swig_type_info *ty) { return ty->name; } /* Return the pretty name associated with this type, that is an unmangled type name in a form presentable to the user. */ SWIGRUNTIME const char * SWIG_TypePrettyName(const swig_type_info *type) { /* The "str" field contains the equivalent pretty names of the type, separated by vertical-bar characters. We choose to print the last name, as it is often (?) the most specific. */ if (!type) return NULL; if (type->str != NULL) { const char *last_name = type->str; const char *s; for (s = type->str; *s; s++) if (*s == '|') last_name = s+1; return last_name; } else return type->name; } /* Set the clientdata field for a type */ SWIGRUNTIME void SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { swig_cast_info *cast = ti->cast; /* if (ti->clientdata == clientdata) return; */ ti->clientdata = clientdata; while (cast) { if (!cast->converter) { swig_type_info *tc = cast->type; if (!tc->clientdata) { SWIG_TypeClientData(tc, clientdata); } } cast = cast->next; } } SWIGRUNTIME void SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { SWIG_TypeClientData(ti, clientdata); ti->owndata = 1; } /* Search for a swig_type_info structure only by mangled name Search is a O(log #types) We start searching at module start, and finish searching when start == end. Note: if start == end at the beginning of the function, we go all the way around the circular list. */ SWIGRUNTIME swig_type_info * SWIG_MangledTypeQueryModule(swig_module_info *start, swig_module_info *end, const char *name) { swig_module_info *iter = start; do { if (iter->size) { register size_t l = 0; register size_t r = iter->size - 1; do { /* since l+r >= 0, we can (>> 1) instead (/ 2) */ register size_t i = (l + r) >> 1; const char *iname = iter->types[i]->name; if (iname) { register int compare = strcmp(name, iname); if (compare == 0) { return iter->types[i]; } else if (compare < 0) { if (i) { r = i - 1; } else { break; } } else if (compare > 0) { l = i + 1; } } else { break; /* should never happen */ } } while (l <= r); } iter = iter->next; } while (iter != end); return 0; } /* Search for a swig_type_info structure for either a mangled name or a human readable name. It first searches the mangled names of the types, which is a O(log #types) If a type is not found it then searches the human readable names, which is O(#types). We start searching at module start, and finish searching when start == end. Note: if start == end at the beginning of the function, we go all the way around the circular list. */ SWIGRUNTIME swig_type_info * SWIG_TypeQueryModule(swig_module_info *start, swig_module_info *end, const char *name) { /* STEP 1: Search the name field using binary search */ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); if (ret) { return ret; } else { /* STEP 2: If the type hasn't been found, do a complete search of the str field (the human readable name) */ swig_module_info *iter = start; do { register size_t i = 0; for (; i < iter->size; ++i) { if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) return iter->types[i]; } iter = iter->next; } while (iter != end); } /* neither found a match */ return 0; } /* Pack binary data into a string */ SWIGRUNTIME char * SWIG_PackData(char *c, void *ptr, size_t sz) { static const char hex[17] = "0123456789abcdef"; register const unsigned char *u = (unsigned char *) ptr; register const unsigned char *eu = u + sz; for (; u != eu; ++u) { register unsigned char uu = *u; *(c++) = hex[(uu & 0xf0) >> 4]; *(c++) = hex[uu & 0xf]; } return c; } /* Unpack binary data from a string */ SWIGRUNTIME const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { register unsigned char *u = (unsigned char *) ptr; register const unsigned char *eu = u + sz; for (; u != eu; ++u) { register char d = *(c++); register unsigned char uu; if ((d >= '0') && (d <= '9')) uu = ((d - '0') << 4); else if ((d >= 'a') && (d <= 'f')) uu = ((d - ('a'-10)) << 4); else return (char *) 0; d = *(c++); if ((d >= '0') && (d <= '9')) uu |= (d - '0'); else if ((d >= 'a') && (d <= 'f')) uu |= (d - ('a'-10)); else return (char *) 0; *u = uu; } return c; } /* Pack 'void *' into a string buffer. */ SWIGRUNTIME char * SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { char *r = buff; if ((2*sizeof(void *) + 2) > bsz) return 0; *(r++) = '_'; r = SWIG_PackData(r,&ptr,sizeof(void *)); if (strlen(name) + 1 > (bsz - (r - buff))) return 0; strcpy(r,name); return buff; } SWIGRUNTIME const char * SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { if (*c != '_') { if (strcmp(c,"NULL") == 0) { *ptr = (void *) 0; return name; } else { return 0; } } return SWIG_UnpackData(++c,ptr,sizeof(void *)); } SWIGRUNTIME char * SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { char *r = buff; size_t lname = (name ? strlen(name) : 0); if ((2*sz + 2 + lname) > bsz) return 0; *(r++) = '_'; r = SWIG_PackData(r,ptr,sz); if (lname) { strncpy(r,name,lname+1); } else { *r = 0; } return buff; } SWIGRUNTIME const char * SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { if (*c != '_') { if (strcmp(c,"NULL") == 0) { memset(ptr,0,sz); return name; } else { return 0; } } return SWIG_UnpackData(++c,ptr,sz); } #ifdef __cplusplus } #endif /* Errors in SWIG */ #define SWIG_UnknownError -1 #define SWIG_IOError -2 #define SWIG_RuntimeError -3 #define SWIG_IndexError -4 #define SWIG_TypeError -5 #define SWIG_DivisionByZero -6 #define SWIG_OverflowError -7 #define SWIG_SyntaxError -8 #define SWIG_ValueError -9 #define SWIG_SystemError -10 #define SWIG_AttributeError -11 #define SWIG_MemoryError -12 #define SWIG_NullReferenceError -13 /* Compatibility macros for Python 3 */ #if PY_VERSION_HEX >= 0x03000000 #define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) #define PyInt_Check(x) PyLong_Check(x) #define PyInt_AsLong(x) PyLong_AsLong(x) #define PyInt_FromLong(x) PyLong_FromLong(x) #define PyString_Check(name) PyBytes_Check(name) #define PyString_FromString(x) PyUnicode_FromString(x) #define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) #define PyString_AsString(str) PyBytes_AsString(str) #define PyString_Size(str) PyBytes_Size(str) #define PyString_InternFromString(key) PyUnicode_InternFromString(key) #define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE #define PyString_AS_STRING(x) PyUnicode_AS_STRING(x) #define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) #endif #ifndef Py_TYPE # define Py_TYPE(op) ((op)->ob_type) #endif /* SWIG APIs for compatibility of both Python 2 & 3 */ #if PY_VERSION_HEX >= 0x03000000 # define SWIG_Python_str_FromFormat PyUnicode_FromFormat #else # define SWIG_Python_str_FromFormat PyString_FromFormat #endif /* Warning: This function will allocate a new string in Python 3, * so please call SWIG_Python_str_DelForPy3(x) to free the space. */ SWIGINTERN char* SWIG_Python_str_AsChar(PyObject *str) { #if PY_VERSION_HEX >= 0x03000000 char *cstr; char *newstr; Py_ssize_t len; str = PyUnicode_AsUTF8String(str); PyBytes_AsStringAndSize(str, &cstr, &len); newstr = (char *) malloc(len+1); memcpy(newstr, cstr, len+1); Py_XDECREF(str); return newstr; #else return PyString_AsString(str); #endif } #if PY_VERSION_HEX >= 0x03000000 # define SWIG_Python_str_DelForPy3(x) free( (void*) (x) ) #else # define SWIG_Python_str_DelForPy3(x) #endif SWIGINTERN PyObject* SWIG_Python_str_FromChar(const char *c) { #if PY_VERSION_HEX >= 0x03000000 return PyUnicode_FromString(c); #else return PyString_FromString(c); #endif } /* Add PyOS_snprintf for old Pythons */ #if PY_VERSION_HEX < 0x02020000 # if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # define PyOS_snprintf _snprintf # else # define PyOS_snprintf snprintf # endif #endif /* A crude PyString_FromFormat implementation for old Pythons */ #if PY_VERSION_HEX < 0x02020000 #ifndef SWIG_PYBUFFER_SIZE # define SWIG_PYBUFFER_SIZE 1024 #endif static PyObject * PyString_FromFormat(const char *fmt, ...) { va_list ap; char buf[SWIG_PYBUFFER_SIZE * 2]; int res; va_start(ap, fmt); res = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); } #endif /* Add PyObject_Del for old Pythons */ #if PY_VERSION_HEX < 0x01060000 # define PyObject_Del(op) PyMem_DEL((op)) #endif #ifndef PyObject_DEL # define PyObject_DEL PyObject_Del #endif /* A crude PyExc_StopIteration exception for old Pythons */ #if PY_VERSION_HEX < 0x02020000 # ifndef PyExc_StopIteration # define PyExc_StopIteration PyExc_RuntimeError # endif # ifndef PyObject_GenericGetAttr # define PyObject_GenericGetAttr 0 # endif #endif /* Py_NotImplemented is defined in 2.1 and up. */ #if PY_VERSION_HEX < 0x02010000 # ifndef Py_NotImplemented # define Py_NotImplemented PyExc_RuntimeError # endif #endif /* A crude PyString_AsStringAndSize implementation for old Pythons */ #if PY_VERSION_HEX < 0x02010000 # ifndef PyString_AsStringAndSize # define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} # endif #endif /* PySequence_Size for old Pythons */ #if PY_VERSION_HEX < 0x02000000 # ifndef PySequence_Size # define PySequence_Size PySequence_Length # endif #endif /* PyBool_FromLong for old Pythons */ #if PY_VERSION_HEX < 0x02030000 static PyObject *PyBool_FromLong(long ok) { PyObject *result = ok ? Py_True : Py_False; Py_INCREF(result); return result; } #endif /* Py_ssize_t for old Pythons */ /* This code is as recommended by: */ /* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) typedef int Py_ssize_t; # define PY_SSIZE_T_MAX INT_MAX # define PY_SSIZE_T_MIN INT_MIN typedef inquiry lenfunc; typedef intargfunc ssizeargfunc; typedef intintargfunc ssizessizeargfunc; typedef intobjargproc ssizeobjargproc; typedef intintobjargproc ssizessizeobjargproc; typedef getreadbufferproc readbufferproc; typedef getwritebufferproc writebufferproc; typedef getsegcountproc segcountproc; typedef getcharbufferproc charbufferproc; static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc)) { long result = 0; PyObject *i = PyNumber_Int(x); if (i) { result = PyInt_AsLong(i); Py_DECREF(i); } return result; } #endif #if PY_VERSION_HEX < 0x02040000 #define Py_VISIT(op) \ do { \ if (op) { \ int vret = visit((op), arg); \ if (vret) \ return vret; \ } \ } while (0) #endif #if PY_VERSION_HEX < 0x02030000 typedef struct { PyTypeObject type; PyNumberMethods as_number; PyMappingMethods as_mapping; PySequenceMethods as_sequence; PyBufferProcs as_buffer; PyObject *name, *slots; } PyHeapTypeObject; #endif #if PY_VERSION_HEX < 0x02030000 typedef destructor freefunc; #endif #if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \ (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \ (PY_MAJOR_VERSION > 3)) # define SWIGPY_USE_CAPSULE # define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME) #endif #if PY_VERSION_HEX < 0x03020000 #define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) #define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) #endif /* ----------------------------------------------------------------------------- * error manipulation * ----------------------------------------------------------------------------- */ SWIGRUNTIME PyObject* SWIG_Python_ErrorType(int code) { PyObject* type = 0; switch(code) { case SWIG_MemoryError: type = PyExc_MemoryError; break; case SWIG_IOError: type = PyExc_IOError; break; case SWIG_RuntimeError: type = PyExc_RuntimeError; break; case SWIG_IndexError: type = PyExc_IndexError; break; case SWIG_TypeError: type = PyExc_TypeError; break; case SWIG_DivisionByZero: type = PyExc_ZeroDivisionError; break; case SWIG_OverflowError: type = PyExc_OverflowError; break; case SWIG_SyntaxError: type = PyExc_SyntaxError; break; case SWIG_ValueError: type = PyExc_ValueError; break; case SWIG_SystemError: type = PyExc_SystemError; break; case SWIG_AttributeError: type = PyExc_AttributeError; break; default: type = PyExc_RuntimeError; } return type; } SWIGRUNTIME void SWIG_Python_AddErrorMsg(const char* mesg) { PyObject *type = 0; PyObject *value = 0; PyObject *traceback = 0; if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); if (value) { char *tmp; PyObject *old_str = PyObject_Str(value); PyErr_Clear(); Py_XINCREF(type); PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg); SWIG_Python_str_DelForPy3(tmp); Py_DECREF(old_str); Py_DECREF(value); } else { PyErr_SetString(PyExc_RuntimeError, mesg); } } #if defined(SWIG_PYTHON_NO_THREADS) # if defined(SWIG_PYTHON_THREADS) # undef SWIG_PYTHON_THREADS # endif #endif #if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ # if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) # if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ # define SWIG_PYTHON_USE_GIL # endif # endif # if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ # ifndef SWIG_PYTHON_INITIALIZE_THREADS # define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() # endif # ifdef __cplusplus /* C++ code */ class SWIG_Python_Thread_Block { bool status; PyGILState_STATE state; public: void end() { if (status) { PyGILState_Release(state); status = false;} } SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} ~SWIG_Python_Thread_Block() { end(); } }; class SWIG_Python_Thread_Allow { bool status; PyThreadState *save; public: void end() { if (status) { PyEval_RestoreThread(save); status = false; }} SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} ~SWIG_Python_Thread_Allow() { end(); } }; # define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block # define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() # define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow # define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() # else /* C code */ # define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() # define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) # define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() # define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) # endif # else /* Old thread way, not implemented, user must provide it */ # if !defined(SWIG_PYTHON_INITIALIZE_THREADS) # define SWIG_PYTHON_INITIALIZE_THREADS # endif # if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) # define SWIG_PYTHON_THREAD_BEGIN_BLOCK # endif # if !defined(SWIG_PYTHON_THREAD_END_BLOCK) # define SWIG_PYTHON_THREAD_END_BLOCK # endif # if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) # define SWIG_PYTHON_THREAD_BEGIN_ALLOW # endif # if !defined(SWIG_PYTHON_THREAD_END_ALLOW) # define SWIG_PYTHON_THREAD_END_ALLOW # endif # endif #else /* No thread support */ # define SWIG_PYTHON_INITIALIZE_THREADS # define SWIG_PYTHON_THREAD_BEGIN_BLOCK # define SWIG_PYTHON_THREAD_END_BLOCK # define SWIG_PYTHON_THREAD_BEGIN_ALLOW # define SWIG_PYTHON_THREAD_END_ALLOW #endif /* ----------------------------------------------------------------------------- * Python API portion that goes into the runtime * ----------------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" { #endif /* ----------------------------------------------------------------------------- * Constant declarations * ----------------------------------------------------------------------------- */ /* Constant Types */ #define SWIG_PY_POINTER 4 #define SWIG_PY_BINARY 5 /* Constant information structure */ typedef struct swig_const_info { int type; char *name; long lvalue; double dvalue; void *pvalue; swig_type_info **ptype; } swig_const_info; /* ----------------------------------------------------------------------------- * Wrapper of PyInstanceMethod_New() used in Python 3 * It is exported to the generated module, used for -fastproxy * ----------------------------------------------------------------------------- */ #if PY_VERSION_HEX >= 0x03000000 SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) { return PyInstanceMethod_New(func); } #else SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func)) { return NULL; } #endif #ifdef __cplusplus } #endif /* ----------------------------------------------------------------------------- * pyrun.swg * * This file contains the runtime support for Python modules * and includes code for managing global variables and pointer * type checking. * * ----------------------------------------------------------------------------- */ /* Common SWIG API */ /* for raw pointers */ #define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) #define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) #define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) #ifdef SWIGPYTHON_BUILTIN #define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags) #else #define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) #endif #define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) #define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) #define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) #define swig_owntype int /* for raw packed data */ #define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) #define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) /* for class or struct pointers */ #define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) #define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) /* for C or C++ function pointers */ #define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) #define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0) /* for C++ member pointers, ie, member methods */ #define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) #define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) /* Runtime API */ #define SWIG_GetModule(clientdata) SWIG_Python_GetModule() #define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) #define SWIG_NewClientData(obj) SwigPyClientData_New(obj) #define SWIG_SetErrorObj SWIG_Python_SetErrorObj #define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg #define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) #define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) #define SWIG_fail goto fail /* Runtime API implementation */ /* Error manipulation */ SWIGINTERN void SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyErr_SetObject(errtype, obj); Py_DECREF(obj); SWIG_PYTHON_THREAD_END_BLOCK; } SWIGINTERN void SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyErr_SetString(errtype, (char *) msg); SWIG_PYTHON_THREAD_END_BLOCK; } #define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) /* Set a constant value */ #if defined(SWIGPYTHON_BUILTIN) SWIGINTERN void SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) { PyObject *s = PyString_InternFromString(key); PyList_Append(seq, s); Py_DECREF(s); } SWIGINTERN void SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) { PyDict_SetItemString(d, (char *)name, obj); Py_DECREF(obj); if (public_interface) SwigPyBuiltin_AddPublicSymbol(public_interface, name); } #else SWIGINTERN void SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { PyDict_SetItemString(d, (char *)name, obj); Py_DECREF(obj); } #endif /* Append a value to the result obj */ SWIGINTERN PyObject* SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { #if !defined(SWIG_PYTHON_OUTPUT_TUPLE) if (!result) { result = obj; } else if (result == Py_None) { Py_DECREF(result); result = obj; } else { if (!PyList_Check(result)) { PyObject *o2 = result; result = PyList_New(1); PyList_SetItem(result, 0, o2); } PyList_Append(result,obj); Py_DECREF(obj); } return result; #else PyObject* o2; PyObject* o3; if (!result) { result = obj; } else if (result == Py_None) { Py_DECREF(result); result = obj; } else { if (!PyTuple_Check(result)) { o2 = result; result = PyTuple_New(1); PyTuple_SET_ITEM(result, 0, o2); } o3 = PyTuple_New(1); PyTuple_SET_ITEM(o3, 0, obj); o2 = result; result = PySequence_Concat(o2, o3); Py_DECREF(o2); Py_DECREF(o3); } return result; #endif } /* Unpack the argument tuple */ SWIGINTERN int SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) { if (!args) { if (!min && !max) { return 1; } else { PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", name, (min == max ? "" : "at least "), (int)min); return 0; } } if (!PyTuple_Check(args)) { if (min <= 1 && max >= 1) { register int i; objs[0] = args; for (i = 1; i < max; ++i) { objs[i] = 0; } return 2; } PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); return 0; } else { register Py_ssize_t l = PyTuple_GET_SIZE(args); if (l < min) { PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", name, (min == max ? "" : "at least "), (int)min, (int)l); return 0; } else if (l > max) { PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", name, (min == max ? "" : "at most "), (int)max, (int)l); return 0; } else { register int i; for (i = 0; i < l; ++i) { objs[i] = PyTuple_GET_ITEM(args, i); } for (; l < max; ++l) { objs[l] = 0; } return i + 1; } } } /* A functor is a function object with one single object argument */ #if PY_VERSION_HEX >= 0x02020000 #define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); #else #define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); #endif /* Helper for static pointer initialization for both C and C++ code, for example static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); */ #ifdef __cplusplus #define SWIG_STATIC_POINTER(var) var #else #define SWIG_STATIC_POINTER(var) var = 0; if (!var) var #endif /* ----------------------------------------------------------------------------- * Pointer declarations * ----------------------------------------------------------------------------- */ /* Flags for new pointer objects */ #define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) #define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) #define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) #define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2) #define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN) #ifdef __cplusplus extern "C" { #endif /* How to access Py_None */ #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # ifndef SWIG_PYTHON_NO_BUILD_NONE # ifndef SWIG_PYTHON_BUILD_NONE # define SWIG_PYTHON_BUILD_NONE # endif # endif #endif #ifdef SWIG_PYTHON_BUILD_NONE # ifdef Py_None # undef Py_None # define Py_None SWIG_Py_None() # endif SWIGRUNTIMEINLINE PyObject * _SWIG_Py_None(void) { PyObject *none = Py_BuildValue((char*)""); Py_DECREF(none); return none; } SWIGRUNTIME PyObject * SWIG_Py_None(void) { static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); return none; } #endif /* The python void return value */ SWIGRUNTIMEINLINE PyObject * SWIG_Py_Void(void) { PyObject *none = Py_None; Py_INCREF(none); return none; } /* SwigPyClientData */ typedef struct { PyObject *klass; PyObject *newraw; PyObject *newargs; PyObject *destroy; int delargs; int implicitconv; PyTypeObject *pytype; } SwigPyClientData; SWIGRUNTIMEINLINE int SWIG_Python_CheckImplicit(swig_type_info *ty) { SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; return data ? data->implicitconv : 0; } SWIGRUNTIMEINLINE PyObject * SWIG_Python_ExceptionType(swig_type_info *desc) { SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; PyObject *klass = data ? data->klass : 0; return (klass ? klass : PyExc_RuntimeError); } SWIGRUNTIME SwigPyClientData * SwigPyClientData_New(PyObject* obj) { if (!obj) { return 0; } else { SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); /* the klass element */ data->klass = obj; Py_INCREF(data->klass); /* the newraw method and newargs arguments used to create a new raw instance */ if (PyClass_Check(obj)) { data->newraw = 0; data->newargs = obj; Py_INCREF(obj); } else { #if (PY_VERSION_HEX < 0x02020000) data->newraw = 0; #else data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); #endif if (data->newraw) { Py_INCREF(data->newraw); data->newargs = PyTuple_New(1); PyTuple_SetItem(data->newargs, 0, obj); } else { data->newargs = obj; } Py_INCREF(data->newargs); } /* the destroy method, aka as the C++ delete method */ data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); if (PyErr_Occurred()) { PyErr_Clear(); data->destroy = 0; } if (data->destroy) { int flags; Py_INCREF(data->destroy); flags = PyCFunction_GET_FLAGS(data->destroy); #ifdef METH_O data->delargs = !(flags & (METH_O)); #else data->delargs = 0; #endif } else { data->delargs = 0; } data->implicitconv = 0; data->pytype = 0; return data; } } SWIGRUNTIME void SwigPyClientData_Del(SwigPyClientData *data) { Py_XDECREF(data->newraw); Py_XDECREF(data->newargs); Py_XDECREF(data->destroy); } /* =============== SwigPyObject =====================*/ typedef struct { PyObject_HEAD void *ptr; swig_type_info *ty; int own; PyObject *next; #ifdef SWIGPYTHON_BUILTIN PyObject *dict; #endif } SwigPyObject; SWIGRUNTIME PyObject * SwigPyObject_long(SwigPyObject *v) { return PyLong_FromVoidPtr(v->ptr); } SWIGRUNTIME PyObject * SwigPyObject_format(const char* fmt, SwigPyObject *v) { PyObject *res = NULL; PyObject *args = PyTuple_New(1); if (args) { if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) { PyObject *ofmt = SWIG_Python_str_FromChar(fmt); if (ofmt) { #if PY_VERSION_HEX >= 0x03000000 res = PyUnicode_Format(ofmt,args); #else res = PyString_Format(ofmt,args); #endif Py_DECREF(ofmt); } Py_DECREF(args); } } return res; } SWIGRUNTIME PyObject * SwigPyObject_oct(SwigPyObject *v) { return SwigPyObject_format("%o",v); } SWIGRUNTIME PyObject * SwigPyObject_hex(SwigPyObject *v) { return SwigPyObject_format("%x",v); } SWIGRUNTIME PyObject * #ifdef METH_NOARGS SwigPyObject_repr(SwigPyObject *v) #else SwigPyObject_repr(SwigPyObject *v, PyObject *args) #endif { const char *name = SWIG_TypePrettyName(v->ty); PyObject *repr = SWIG_Python_str_FromFormat("", name, (void *)v); if (v->next) { # ifdef METH_NOARGS PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); # else PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args); # endif # if PY_VERSION_HEX >= 0x03000000 PyObject *joined = PyUnicode_Concat(repr, nrep); Py_DecRef(repr); Py_DecRef(nrep); repr = joined; # else PyString_ConcatAndDel(&repr,nrep); # endif } return repr; } SWIGRUNTIME int SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { char *str; #ifdef METH_NOARGS PyObject *repr = SwigPyObject_repr(v); #else PyObject *repr = SwigPyObject_repr(v, NULL); #endif if (repr) { str = SWIG_Python_str_AsChar(repr); fputs(str, fp); SWIG_Python_str_DelForPy3(str); Py_DECREF(repr); return 0; } else { return 1; } } SWIGRUNTIME PyObject * SwigPyObject_str(SwigPyObject *v) { char result[SWIG_BUFFER_SIZE]; return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? SWIG_Python_str_FromChar(result) : 0; } SWIGRUNTIME int SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) { void *i = v->ptr; void *j = w->ptr; return (i < j) ? -1 : ((i > j) ? 1 : 0); } /* Added for Python 3.x, would it also be useful for Python 2.x? */ SWIGRUNTIME PyObject* SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) { PyObject* res; if( op != Py_EQ && op != Py_NE ) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0); return res; } SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void); #ifdef SWIGPYTHON_BUILTIN static swig_type_info *SwigPyObject_stype = 0; SWIGRUNTIME PyTypeObject* SwigPyObject_type(void) { SwigPyClientData *cd; assert(SwigPyObject_stype); cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; assert(cd); assert(cd->pytype); return cd->pytype; } #else SWIGRUNTIME PyTypeObject* SwigPyObject_type(void) { static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce(); return type; } #endif SWIGRUNTIMEINLINE int SwigPyObject_Check(PyObject *op) { #ifdef SWIGPYTHON_BUILTIN PyTypeObject *target_tp = SwigPyObject_type(); if (PyType_IsSubtype(op->ob_type, target_tp)) return 1; return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0); #else return (Py_TYPE(op) == SwigPyObject_type()) || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0); #endif } SWIGRUNTIME PyObject * SwigPyObject_New(void *ptr, swig_type_info *ty, int own); SWIGRUNTIME void SwigPyObject_dealloc(PyObject *v) { SwigPyObject *sobj = (SwigPyObject *) v; PyObject *next = sobj->next; if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; if (destroy) { /* destroy is always a VARARGS method */ PyObject *res; if (data->delargs) { /* we need to create a temporary object to carry the destroy operation */ PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); res = SWIG_Python_CallFunctor(destroy, tmp); Py_DECREF(tmp); } else { PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); PyObject *mself = PyCFunction_GET_SELF(destroy); res = ((*meth)(mself, v)); } Py_XDECREF(res); } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) else { const char *name = SWIG_TypePrettyName(ty); printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } #endif } Py_XDECREF(next); PyObject_DEL(v); } SWIGRUNTIME PyObject* SwigPyObject_append(PyObject* v, PyObject* next) { SwigPyObject *sobj = (SwigPyObject *) v; #ifndef METH_O PyObject *tmp = 0; if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; next = tmp; #endif if (!SwigPyObject_Check(next)) { return NULL; } sobj->next = next; Py_INCREF(next); return SWIG_Py_Void(); } SWIGRUNTIME PyObject* #ifdef METH_NOARGS SwigPyObject_next(PyObject* v) #else SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) #endif { SwigPyObject *sobj = (SwigPyObject *) v; if (sobj->next) { Py_INCREF(sobj->next); return sobj->next; } else { return SWIG_Py_Void(); } } SWIGINTERN PyObject* #ifdef METH_NOARGS SwigPyObject_disown(PyObject *v) #else SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) #endif { SwigPyObject *sobj = (SwigPyObject *)v; sobj->own = 0; return SWIG_Py_Void(); } SWIGINTERN PyObject* #ifdef METH_NOARGS SwigPyObject_acquire(PyObject *v) #else SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) #endif { SwigPyObject *sobj = (SwigPyObject *)v; sobj->own = SWIG_POINTER_OWN; return SWIG_Py_Void(); } SWIGINTERN PyObject* SwigPyObject_own(PyObject *v, PyObject *args) { PyObject *val = 0; #if (PY_VERSION_HEX < 0x02020000) if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) #else if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) #endif { return NULL; } else { SwigPyObject *sobj = (SwigPyObject *)v; PyObject *obj = PyBool_FromLong(sobj->own); if (val) { #ifdef METH_NOARGS if (PyObject_IsTrue(val)) { SwigPyObject_acquire(v); } else { SwigPyObject_disown(v); } #else if (PyObject_IsTrue(val)) { SwigPyObject_acquire(v,args); } else { SwigPyObject_disown(v,args); } #endif } return obj; } } #ifdef METH_O static PyMethodDef swigobject_methods[] = { {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, {(char *)"append", (PyCFunction)SwigPyObject_append, METH_O, (char *)"appends another 'this' object"}, {(char *)"next", (PyCFunction)SwigPyObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_NOARGS, (char *)"returns object representation"}, {0, 0, 0, 0} }; #else static PyMethodDef swigobject_methods[] = { {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, {(char *)"append", (PyCFunction)SwigPyObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, {(char *)"next", (PyCFunction)SwigPyObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_VARARGS, (char *)"returns object representation"}, {0, 0, 0, 0} }; #endif #if PY_VERSION_HEX < 0x02020000 SWIGINTERN PyObject * SwigPyObject_getattr(SwigPyObject *sobj,char *name) { return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); } #endif SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void) { static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; static PyNumberMethods SwigPyObject_as_number = { (binaryfunc)0, /*nb_add*/ (binaryfunc)0, /*nb_subtract*/ (binaryfunc)0, /*nb_multiply*/ /* nb_divide removed in Python 3 */ #if PY_VERSION_HEX < 0x03000000 (binaryfunc)0, /*nb_divide*/ #endif (binaryfunc)0, /*nb_remainder*/ (binaryfunc)0, /*nb_divmod*/ (ternaryfunc)0,/*nb_power*/ (unaryfunc)0, /*nb_negative*/ (unaryfunc)0, /*nb_positive*/ (unaryfunc)0, /*nb_absolute*/ (inquiry)0, /*nb_nonzero*/ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ 0, /*nb_and*/ 0, /*nb_xor*/ 0, /*nb_or*/ #if PY_VERSION_HEX < 0x03000000 0, /*nb_coerce*/ #endif (unaryfunc)SwigPyObject_long, /*nb_int*/ #if PY_VERSION_HEX < 0x03000000 (unaryfunc)SwigPyObject_long, /*nb_long*/ #else 0, /*nb_reserved*/ #endif (unaryfunc)0, /*nb_float*/ #if PY_VERSION_HEX < 0x03000000 (unaryfunc)SwigPyObject_oct, /*nb_oct*/ (unaryfunc)SwigPyObject_hex, /*nb_hex*/ #endif #if PY_VERSION_HEX >= 0x03000000 /* 3.0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ #elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ #elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ #elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ #endif }; static PyTypeObject swigpyobject_type; static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX >= 0x03000000 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ #endif (char *)"SwigPyObject", /* tp_name */ sizeof(SwigPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)SwigPyObject_dealloc, /* tp_dealloc */ (printfunc)SwigPyObject_print, /* tp_print */ #if PY_VERSION_HEX < 0x02020000 (getattrfunc)SwigPyObject_getattr, /* tp_getattr */ #else (getattrfunc)0, /* tp_getattr */ #endif (setattrfunc)0, /* tp_setattr */ #if PY_VERSION_HEX >= 0x03000000 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ #else (cmpfunc)SwigPyObject_compare, /* tp_compare */ #endif (reprfunc)SwigPyObject_repr, /* tp_repr */ &SwigPyObject_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)SwigPyObject_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ swigobject_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */ 0, /* tp_weaklistoffset */ #if PY_VERSION_HEX >= 0x02020000 0, /* tp_iter */ 0, /* tp_iternext */ swigobject_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ #endif #if PY_VERSION_HEX >= 0x02030000 0, /* tp_del */ #endif #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version */ #endif #ifdef COUNT_ALLOCS 0,0,0,0 /* tp_alloc -> tp_next */ #endif }; swigpyobject_type = tmp; type_init = 1; #if PY_VERSION_HEX < 0x02020000 swigpyobject_type.ob_type = &PyType_Type; #else if (PyType_Ready(&swigpyobject_type) < 0) return NULL; #endif } return &swigpyobject_type; } SWIGRUNTIME PyObject * SwigPyObject_New(void *ptr, swig_type_info *ty, int own) { SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type()); if (sobj) { sobj->ptr = ptr; sobj->ty = ty; sobj->own = own; sobj->next = 0; } return (PyObject *)sobj; } /* ----------------------------------------------------------------------------- * Implements a simple Swig Packed type, and use it instead of string * ----------------------------------------------------------------------------- */ typedef struct { PyObject_HEAD void *pack; swig_type_info *ty; size_t size; } SwigPyPacked; SWIGRUNTIME int SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { char result[SWIG_BUFFER_SIZE]; fputs("pack, v->size, 0, sizeof(result))) { fputs("at ", fp); fputs(result, fp); } fputs(v->ty->name,fp); fputs(">", fp); return 0; } SWIGRUNTIME PyObject * SwigPyPacked_repr(SwigPyPacked *v) { char result[SWIG_BUFFER_SIZE]; if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { return SWIG_Python_str_FromFormat("", result, v->ty->name); } else { return SWIG_Python_str_FromFormat("", v->ty->name); } } SWIGRUNTIME PyObject * SwigPyPacked_str(SwigPyPacked *v) { char result[SWIG_BUFFER_SIZE]; if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); } else { return SWIG_Python_str_FromChar(v->ty->name); } } SWIGRUNTIME int SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) { size_t i = v->size; size_t j = w->size; int s = (i < j) ? -1 : ((i > j) ? 1 : 0); return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); } SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void); SWIGRUNTIME PyTypeObject* SwigPyPacked_type(void) { static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce(); return type; } SWIGRUNTIMEINLINE int SwigPyPacked_Check(PyObject *op) { return ((op)->ob_type == SwigPyPacked_TypeOnce()) || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0); } SWIGRUNTIME void SwigPyPacked_dealloc(PyObject *v) { if (SwigPyPacked_Check(v)) { SwigPyPacked *sobj = (SwigPyPacked *) v; free(sobj->pack); } PyObject_DEL(v); } SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void) { static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; static PyTypeObject swigpypacked_type; static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX>=0x03000000 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ #endif (char *)"SwigPyPacked", /* tp_name */ sizeof(SwigPyPacked), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ (printfunc)SwigPyPacked_print, /* tp_print */ (getattrfunc)0, /* tp_getattr */ (setattrfunc)0, /* tp_setattr */ #if PY_VERSION_HEX>=0x03000000 0, /* tp_reserved in 3.0.1 */ #else (cmpfunc)SwigPyPacked_compare, /* tp_compare */ #endif (reprfunc)SwigPyPacked_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)SwigPyPacked_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ swigpacked_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ #if PY_VERSION_HEX >= 0x02020000 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ #endif #if PY_VERSION_HEX >= 0x02030000 0, /* tp_del */ #endif #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version */ #endif #ifdef COUNT_ALLOCS 0,0,0,0 /* tp_alloc -> tp_next */ #endif }; swigpypacked_type = tmp; type_init = 1; #if PY_VERSION_HEX < 0x02020000 swigpypacked_type.ob_type = &PyType_Type; #else if (PyType_Ready(&swigpypacked_type) < 0) return NULL; #endif } return &swigpypacked_type; } SWIGRUNTIME PyObject * SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) { SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type()); if (sobj) { void *pack = malloc(size); if (pack) { memcpy(pack, ptr, size); sobj->pack = pack; sobj->ty = ty; sobj->size = size; } else { PyObject_DEL((PyObject *) sobj); sobj = 0; } } return (PyObject *) sobj; } SWIGRUNTIME swig_type_info * SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) { if (SwigPyPacked_Check(obj)) { SwigPyPacked *sobj = (SwigPyPacked *)obj; if (sobj->size != size) return 0; memcpy(ptr, sobj->pack, size); return sobj->ty; } else { return 0; } } /* ----------------------------------------------------------------------------- * pointers/data manipulation * ----------------------------------------------------------------------------- */ SWIGRUNTIMEINLINE PyObject * _SWIG_This(void) { return SWIG_Python_str_FromChar("this"); } static PyObject *swig_this = NULL; SWIGRUNTIME PyObject * SWIG_This(void) { if (swig_this == NULL) swig_this = _SWIG_This(); return swig_this; } /* #define SWIG_PYTHON_SLOW_GETSET_THIS */ /* TODO: I don't know how to implement the fast getset in Python 3 right now */ #if PY_VERSION_HEX>=0x03000000 #define SWIG_PYTHON_SLOW_GETSET_THIS #endif SWIGRUNTIME SwigPyObject * SWIG_Python_GetSwigThis(PyObject *pyobj) { PyObject *obj; if (SwigPyObject_Check(pyobj)) return (SwigPyObject *) pyobj; #ifdef SWIGPYTHON_BUILTIN (void)obj; # ifdef PyWeakref_CheckProxy if (PyWeakref_CheckProxy(pyobj)) { pyobj = PyWeakref_GET_OBJECT(pyobj); if (pyobj && SwigPyObject_Check(pyobj)) return (SwigPyObject*) pyobj; } # endif return NULL; #else obj = 0; #if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) if (PyInstance_Check(pyobj)) { obj = _PyInstance_Lookup(pyobj, SWIG_This()); } else { PyObject **dictptr = _PyObject_GetDictPtr(pyobj); if (dictptr != NULL) { PyObject *dict = *dictptr; obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; } else { #ifdef PyWeakref_CheckProxy if (PyWeakref_CheckProxy(pyobj)) { PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; } #endif obj = PyObject_GetAttr(pyobj,SWIG_This()); if (obj) { Py_DECREF(obj); } else { if (PyErr_Occurred()) PyErr_Clear(); return 0; } } } #else obj = PyObject_GetAttr(pyobj,SWIG_This()); if (obj) { Py_DECREF(obj); } else { if (PyErr_Occurred()) PyErr_Clear(); return 0; } #endif if (obj && !SwigPyObject_Check(obj)) { /* a PyObject is called 'this', try to get the 'real this' SwigPyObject from it */ return SWIG_Python_GetSwigThis(obj); } return (SwigPyObject *)obj; #endif } /* Acquire a pointer value */ SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { if (own == SWIG_POINTER_OWN) { SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; sobj->own = own; return oldown; } } return 0; } /* Convert a pointer value */ SWIGRUNTIME int SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { int res; SwigPyObject *sobj; if (!obj) return SWIG_ERROR; if (obj == Py_None) { if (ptr) *ptr = 0; return SWIG_OK; } res = SWIG_ERROR; sobj = SWIG_Python_GetSwigThis(obj); if (own) *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { swig_type_info *to = sobj->ty; if (to == ty) { /* no type cast needed */ if (ptr) *ptr = vptr; break; } else { swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); if (!tc) { sobj = (SwigPyObject *)sobj->next; } else { if (ptr) { int newmemory = 0; *ptr = SWIG_TypeCast(tc,vptr,&newmemory); if (newmemory == SWIG_CAST_NEW_MEMORY) { assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ if (own) *own = *own | SWIG_CAST_NEW_MEMORY; } } break; } } } else { if (ptr) *ptr = vptr; break; } } if (sobj) { if (own) *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } res = SWIG_OK; } else { if (flags & SWIG_POINTER_IMPLICIT_CONV) { SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; if (data && !data->implicitconv) { PyObject *klass = data->klass; if (klass) { PyObject *impconv; data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ impconv = SWIG_Python_CallFunctor(klass, obj); data->implicitconv = 0; if (PyErr_Occurred()) { PyErr_Clear(); impconv = 0; } if (impconv) { SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); if (iobj) { void *vptr; res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); if (SWIG_IsOK(res)) { if (ptr) { *ptr = vptr; /* transfer the ownership to 'ptr' */ iobj->own = 0; res = SWIG_AddCast(res); res = SWIG_AddNewMask(res); } else { res = SWIG_AddCast(res); } } } Py_DECREF(impconv); } } } } } return res; } /* Convert a function ptr value */ SWIGRUNTIME int SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { if (!PyCFunction_Check(obj)) { return SWIG_ConvertPtr(obj, ptr, ty, 0); } else { void *vptr = 0; /* here we get the method pointer for callbacks */ const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; if (desc) desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; if (!desc) return SWIG_ERROR; if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); if (tc) { int newmemory = 0; *ptr = SWIG_TypeCast(tc,vptr,&newmemory); assert(!newmemory); /* newmemory handling not yet implemented */ } else { return SWIG_ERROR; } } else { *ptr = vptr; } return SWIG_OK; } } /* Convert a packed value value */ SWIGRUNTIME int SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); if (!to) return SWIG_ERROR; if (ty) { if (to != ty) { /* check type cast? */ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); if (!tc) return SWIG_ERROR; } } return SWIG_OK; } /* ----------------------------------------------------------------------------- * Create a new pointer object * ----------------------------------------------------------------------------- */ /* Create a new instance object, without calling __init__, and set the 'this' attribute. */ SWIGRUNTIME PyObject* SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) { #if (PY_VERSION_HEX >= 0x02020000) PyObject *inst = 0; PyObject *newraw = data->newraw; if (newraw) { inst = PyObject_Call(newraw, data->newargs, NULL); if (inst) { #if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) PyObject **dictptr = _PyObject_GetDictPtr(inst); if (dictptr != NULL) { PyObject *dict = *dictptr; if (dict == NULL) { dict = PyDict_New(); *dictptr = dict; PyDict_SetItem(dict, SWIG_This(), swig_this); } } #else PyObject *key = SWIG_This(); PyObject_SetAttr(inst, key, swig_this); #endif } } else { #if PY_VERSION_HEX >= 0x03000000 inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None); PyObject_SetAttr(inst, SWIG_This(), swig_this); Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; #else PyObject *dict = PyDict_New(); PyDict_SetItem(dict, SWIG_This(), swig_this); inst = PyInstance_NewRaw(data->newargs, dict); Py_DECREF(dict); #endif } return inst; #else #if (PY_VERSION_HEX >= 0x02010000) PyObject *inst; PyObject *dict = PyDict_New(); PyDict_SetItem(dict, SWIG_This(), swig_this); inst = PyInstance_NewRaw(data->newargs, dict); Py_DECREF(dict); return (PyObject *) inst; #else PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); if (inst == NULL) { return NULL; } inst->in_class = (PyClassObject *)data->newargs; Py_INCREF(inst->in_class); inst->in_dict = PyDict_New(); if (inst->in_dict == NULL) { Py_DECREF(inst); return NULL; } #ifdef Py_TPFLAGS_HAVE_WEAKREFS inst->in_weakreflist = NULL; #endif #ifdef Py_TPFLAGS_GC PyObject_GC_Init(inst); #endif PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); return (PyObject *) inst; #endif #endif } SWIGRUNTIME void SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) { PyObject *dict; #if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) PyObject **dictptr = _PyObject_GetDictPtr(inst); if (dictptr != NULL) { dict = *dictptr; if (dict == NULL) { dict = PyDict_New(); *dictptr = dict; } PyDict_SetItem(dict, SWIG_This(), swig_this); return; } #endif dict = PyObject_GetAttrString(inst, (char*)"__dict__"); PyDict_SetItem(dict, SWIG_This(), swig_this); Py_DECREF(dict); } SWIGINTERN PyObject * SWIG_Python_InitShadowInstance(PyObject *args) { PyObject *obj[2]; if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { return NULL; } else { SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); if (sthis) { SwigPyObject_append((PyObject*) sthis, obj[1]); } else { SWIG_Python_SetSwigThis(obj[0], obj[1]); } return SWIG_Py_Void(); } } /* Create a new pointer object */ SWIGRUNTIME PyObject * SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) { SwigPyClientData *clientdata; PyObject * robj; int own; if (!ptr) return SWIG_Py_Void(); clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; if (clientdata && clientdata->pytype) { SwigPyObject *newobj; if (flags & SWIG_BUILTIN_TP_INIT) { newobj = (SwigPyObject*) self; if (newobj->ptr) { PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0); while (newobj->next) newobj = (SwigPyObject *) newobj->next; newobj->next = next_self; newobj = (SwigPyObject *)next_self; } } else { newobj = PyObject_New(SwigPyObject, clientdata->pytype); } if (newobj) { newobj->ptr = ptr; newobj->ty = type; newobj->own = own; newobj->next = 0; #ifdef SWIGPYTHON_BUILTIN newobj->dict = 0; #endif return (PyObject*) newobj; } return SWIG_Py_Void(); } assert(!(flags & SWIG_BUILTIN_TP_INIT)); robj = SwigPyObject_New(ptr, type, own); if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); if (inst) { Py_DECREF(robj); robj = inst; } } return robj; } /* Create a new packed object */ SWIGRUNTIMEINLINE PyObject * SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); } /* -----------------------------------------------------------------------------* * Get type list * -----------------------------------------------------------------------------*/ #ifdef SWIG_LINK_RUNTIME void *SWIG_ReturnGlobalTypeList(void *); #endif SWIGRUNTIME swig_module_info * SWIG_Python_GetModule(void) { static void *type_pointer = (void *)0; /* first check if module already created */ if (!type_pointer) { #ifdef SWIG_LINK_RUNTIME type_pointer = SWIG_ReturnGlobalTypeList((void *)0); #else # ifdef SWIGPY_USE_CAPSULE type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0); # else type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); # endif if (PyErr_Occurred()) { PyErr_Clear(); type_pointer = (void *)0; } #endif } return (swig_module_info *) type_pointer; } #if PY_MAJOR_VERSION < 2 /* PyModule_AddObject function was introduced in Python 2.0. The following function is copied out of Python/modsupport.c in python version 2.3.4 */ SWIGINTERN int PyModule_AddObject(PyObject *m, char *name, PyObject *o) { PyObject *dict; if (!PyModule_Check(m)) { PyErr_SetString(PyExc_TypeError, "PyModule_AddObject() needs module as first arg"); return SWIG_ERROR; } if (!o) { PyErr_SetString(PyExc_TypeError, "PyModule_AddObject() needs non-NULL value"); return SWIG_ERROR; } dict = PyModule_GetDict(m); if (dict == NULL) { /* Internal error -- modules must have a dict! */ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", PyModule_GetName(m)); return SWIG_ERROR; } if (PyDict_SetItemString(dict, name, o)) return SWIG_ERROR; Py_DECREF(o); return SWIG_OK; } #endif SWIGRUNTIME void #ifdef SWIGPY_USE_CAPSULE SWIG_Python_DestroyModule(PyObject *obj) #else SWIG_Python_DestroyModule(void *vptr) #endif { #ifdef SWIGPY_USE_CAPSULE swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME); #else swig_module_info *swig_module = (swig_module_info *) vptr; #endif swig_type_info **types = swig_module->types; size_t i; for (i =0; i < swig_module->size; ++i) { swig_type_info *ty = types[i]; if (ty->owndata) { SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; if (data) SwigPyClientData_Del(data); } } Py_DECREF(SWIG_This()); swig_this = NULL; } SWIGRUNTIME void SWIG_Python_SetModule(swig_module_info *swig_module) { #if PY_VERSION_HEX >= 0x03000000 /* Add a dummy module object into sys.modules */ PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION); #else static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */ PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table); #endif #ifdef SWIGPY_USE_CAPSULE PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule); if (pointer && module) { PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer); } else { Py_XDECREF(pointer); } #else PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); if (pointer && module) { PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); } else { Py_XDECREF(pointer); } #endif } /* The python cached type query */ SWIGRUNTIME PyObject * SWIG_Python_TypeCache(void) { static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); return cache; } SWIGRUNTIME swig_type_info * SWIG_Python_TypeQuery(const char *type) { PyObject *cache = SWIG_Python_TypeCache(); PyObject *key = SWIG_Python_str_FromChar(type); PyObject *obj = PyDict_GetItem(cache, key); swig_type_info *descriptor; if (obj) { #ifdef SWIGPY_USE_CAPSULE descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL); #else descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); #endif } else { swig_module_info *swig_module = SWIG_Python_GetModule(); descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); if (descriptor) { #ifdef SWIGPY_USE_CAPSULE obj = PyCapsule_New((void*) descriptor, NULL, NULL); #else obj = PyCObject_FromVoidPtr(descriptor, NULL); #endif PyDict_SetItem(cache, key, obj); Py_DECREF(obj); } } Py_DECREF(key); return descriptor; } /* For backward compatibility only */ #define SWIG_POINTER_EXCEPTION 0 #define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) #define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) SWIGRUNTIME int SWIG_Python_AddErrMesg(const char* mesg, int infront) { if (PyErr_Occurred()) { PyObject *type = 0; PyObject *value = 0; PyObject *traceback = 0; PyErr_Fetch(&type, &value, &traceback); if (value) { char *tmp; PyObject *old_str = PyObject_Str(value); Py_XINCREF(type); PyErr_Clear(); if (infront) { PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str)); } else { PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg); } SWIG_Python_str_DelForPy3(tmp); Py_DECREF(old_str); } return 1; } else { return 0; } } SWIGRUNTIME int SWIG_Python_ArgFail(int argnum) { if (PyErr_Occurred()) { /* add information about failing argument */ char mesg[256]; PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); return SWIG_Python_AddErrMesg(mesg, 1); } else { return 0; } } SWIGRUNTIMEINLINE const char * SwigPyObject_GetDesc(PyObject *self) { SwigPyObject *v = (SwigPyObject *)self; swig_type_info *ty = v ? v->ty : 0; return ty ? ty->str : (char*)""; } SWIGRUNTIME void SWIG_Python_TypeError(const char *type, PyObject *obj) { if (type) { #if defined(SWIG_COBJECT_TYPES) if (obj && SwigPyObject_Check(obj)) { const char *otype = (const char *) SwigPyObject_GetDesc(obj); if (otype) { PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", type, otype); return; } } else #endif { const char *otype = (obj ? obj->ob_type->tp_name : 0); if (otype) { PyObject *str = PyObject_Str(obj); const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0; if (cstr) { PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", type, otype, cstr); SWIG_Python_str_DelForPy3(cstr); } else { PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", type, otype); } Py_XDECREF(str); return; } } PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); } else { PyErr_Format(PyExc_TypeError, "unexpected type is received"); } } /* Convert a pointer value, signal an exception on a type mismatch */ SWIGRUNTIME void * SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) { void *result; if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { PyErr_Clear(); #if SWIG_POINTER_EXCEPTION if (flags) { SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); SWIG_Python_ArgFail(argnum); } #endif } return result; } SWIGRUNTIME int SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { PyTypeObject *tp = obj->ob_type; PyObject *descr; PyObject *encoded_name; descrsetfunc f; int res; #ifdef Py_USING_UNICODE if (PyString_Check(name)) { name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL); if (!name) return -1; } else if (!PyUnicode_Check(name)) #else if (!PyString_Check(name)) #endif { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name); return -1; } else { Py_INCREF(name); } if (!tp->tp_dict) { if (PyType_Ready(tp) < 0) goto done; } res = -1; descr = _PyType_Lookup(tp, name); f = NULL; if (descr != NULL) f = descr->ob_type->tp_descr_set; if (!f) { if (PyString_Check(name)) { encoded_name = name; Py_INCREF(name); } else { encoded_name = PyUnicode_AsUTF8String(name); } PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name)); Py_DECREF(encoded_name); } else { res = f(descr, obj, value); } done: Py_DECREF(name); return res; } #ifdef __cplusplus } #endif #define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) #define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0) /* -------- TYPES TABLE (BEGIN) -------- */ #define SWIGTYPE_p_char swig_types[0] #define SWIGTYPE_p_int swig_types[1] #define SWIGTYPE_p_uint8_t swig_types[2] static swig_type_info *swig_types[4]; static swig_module_info swig_module = {swig_types, 3, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) /* -------- TYPES TABLE (END) -------- */ #if (PY_VERSION_HEX <= 0x02000000) # if !defined(SWIG_PYTHON_CLASSIC) # error "This python version requires swig to be run with the '-classic' option" # endif #endif /*----------------------------------------------- @(target):= _libwebp.so ------------------------------------------------*/ #if PY_VERSION_HEX >= 0x03000000 # define SWIG_init PyInit__libwebp #else # define SWIG_init init_libwebp #endif #define SWIG_name "_libwebp" #define SWIGVERSION 0x020004 #define SWIG_VERSION SWIGVERSION #define SWIG_as_voidptr(a) (void *)((const void *)(a)) #define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) #define SWIG_From_long PyInt_FromLong SWIGINTERNINLINE PyObject * SWIG_From_int (int value) { return SWIG_From_long (value); } SWIGINTERN swig_type_info* SWIG_pchar_descriptor(void) { static int init = 0; static swig_type_info* info = 0; if (!init) { info = SWIG_TypeQuery("_p_char"); init = 1; } return info; } SWIGINTERN int SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) { #if PY_VERSION_HEX>=0x03000000 if (PyUnicode_Check(obj)) #else if (PyString_Check(obj)) #endif { char *cstr; Py_ssize_t len; #if PY_VERSION_HEX>=0x03000000 if (!alloc && cptr) { /* We can't allow converting without allocation, since the internal representation of string in Python 3 is UCS-2/UCS-4 but we require a UTF-8 representation. TODO(bhy) More detailed explanation */ return SWIG_RuntimeError; } obj = PyUnicode_AsUTF8String(obj); PyBytes_AsStringAndSize(obj, &cstr, &len); if(alloc) *alloc = SWIG_NEWOBJ; #else PyString_AsStringAndSize(obj, &cstr, &len); #endif if (cptr) { if (alloc) { /* In python the user should not be able to modify the inner string representation. To warranty that, if you define SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string buffer is always returned. The default behavior is just to return the pointer value, so, be careful. */ #if defined(SWIG_PYTHON_SAFE_CSTRINGS) if (*alloc != SWIG_OLDOBJ) #else if (*alloc == SWIG_NEWOBJ) #endif { *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); *alloc = SWIG_NEWOBJ; } else { *cptr = cstr; *alloc = SWIG_OLDOBJ; } } else { #if PY_VERSION_HEX>=0x03000000 assert(0); /* Should never reach here in Python 3 */ #endif *cptr = SWIG_Python_str_AsChar(obj); } } if (psize) *psize = len + 1; #if PY_VERSION_HEX>=0x03000000 Py_XDECREF(obj); #endif return SWIG_OK; } else { swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); if (pchar_descriptor) { void* vptr = 0; if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { if (cptr) *cptr = (char *) vptr; if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; if (alloc) *alloc = SWIG_OLDOBJ; return SWIG_OK; } } } return SWIG_TypeError; } SWIGINTERN int SWIG_AsVal_double (PyObject *obj, double *val) { int res = SWIG_TypeError; if (PyFloat_Check(obj)) { if (val) *val = PyFloat_AsDouble(obj); return SWIG_OK; } else if (PyInt_Check(obj)) { if (val) *val = PyInt_AsLong(obj); return SWIG_OK; } else if (PyLong_Check(obj)) { double v = PyLong_AsDouble(obj); if (!PyErr_Occurred()) { if (val) *val = v; return SWIG_OK; } else { PyErr_Clear(); } } #ifdef SWIG_PYTHON_CAST_MODE { int dispatch = 0; double d = PyFloat_AsDouble(obj); if (!PyErr_Occurred()) { if (val) *val = d; return SWIG_AddCast(SWIG_OK); } else { PyErr_Clear(); } if (!dispatch) { long v = PyLong_AsLong(obj); if (!PyErr_Occurred()) { if (val) *val = v; return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); } else { PyErr_Clear(); } } } #endif return res; } #include #include SWIGINTERNINLINE int SWIG_CanCastAsInteger(double *d, double min, double max) { double x = *d; if ((min <= x && x <= max)) { double fx = floor(x); double cx = ceil(x); double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ if ((errno == EDOM) || (errno == ERANGE)) { errno = 0; } else { double summ, reps, diff; if (rd < x) { diff = x - rd; } else if (rd > x) { diff = rd - x; } else { return 1; } summ = rd + x; reps = diff/summ; if (reps < 8*DBL_EPSILON) { *d = rd; return 1; } } } return 0; } SWIGINTERN int SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) { if (PyInt_Check(obj)) { long v = PyInt_AsLong(obj); if (v >= 0) { if (val) *val = v; return SWIG_OK; } else { return SWIG_OverflowError; } } else if (PyLong_Check(obj)) { unsigned long v = PyLong_AsUnsignedLong(obj); if (!PyErr_Occurred()) { if (val) *val = v; return SWIG_OK; } else { PyErr_Clear(); } } #ifdef SWIG_PYTHON_CAST_MODE { int dispatch = 0; unsigned long v = PyLong_AsUnsignedLong(obj); if (!PyErr_Occurred()) { if (val) *val = v; return SWIG_AddCast(SWIG_OK); } else { PyErr_Clear(); } if (!dispatch) { double d; int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { if (val) *val = (unsigned long)(d); return res; } } } #endif return SWIG_TypeError; } SWIGINTERNINLINE int SWIG_AsVal_size_t (PyObject * obj, size_t *val) { unsigned long v; int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); if (SWIG_IsOK(res) && val) *val = (size_t)(v); return res; } #include "webp/decode.h" #include "webp/encode.h" static size_t ReturnedBufferSize( const char* function, int* width, int* height) { static const struct sizemap { const char* function; int size_multiplier; } size_map[] = { #ifdef SWIGJAVA { "Java_com_google_webp_libwebpJNI_WebPDecodeRGB", 3 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeRGBA", 4 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeARGB", 4 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeBGR", 3 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeBGRA", 4 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGB", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGR", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGBA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGRA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGB", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGR", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGBA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGRA", 1 }, #endif #ifdef SWIGPYTHON { "WebPDecodeRGB", 3 }, { "WebPDecodeRGBA", 4 }, { "WebPDecodeARGB", 4 }, { "WebPDecodeBGR", 3 }, { "WebPDecodeBGRA", 4 }, { "wrap_WebPEncodeRGB", 1 }, { "wrap_WebPEncodeBGR", 1 }, { "wrap_WebPEncodeRGBA", 1 }, { "wrap_WebPEncodeBGRA", 1 }, { "wrap_WebPEncodeLosslessRGB", 1 }, { "wrap_WebPEncodeLosslessBGR", 1 }, { "wrap_WebPEncodeLosslessRGBA", 1 }, { "wrap_WebPEncodeLosslessBGRA", 1 }, #endif { NULL, 0 } }; const struct sizemap* p; size_t size = 0; for (p = size_map; p->function; ++p) { if (!strcmp(function, p->function)) { size = *width * *height * p->size_multiplier; break; } } return size; } typedef size_t (*WebPEncodeFunction)(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); typedef size_t (*WebPEncodeLosslessFunction)(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); static uint8_t* EncodeLossy(const uint8_t* rgb, int width, int height, int stride, float quality_factor, WebPEncodeFunction encfn, int* output_size, int* unused) { uint8_t* output = NULL; const size_t image_size = encfn(rgb, width, height, stride, quality_factor, &output); // the values of following two will be interpreted by ReturnedBufferSize() // as 'width' and 'height' in the size calculation. *output_size = image_size; *unused = 1; return image_size ? output : NULL; } static uint8_t* EncodeLossless(const uint8_t* rgb, int width, int height, int stride, WebPEncodeLosslessFunction encfn, int* output_size, int* unused) { uint8_t* output = NULL; const size_t image_size = encfn(rgb, width, height, stride, &output); // the values of the following two will be interpreted by // ReturnedBufferSize() as 'width' and 'height' in the size calculation. *output_size = image_size; *unused = 1; return image_size ? output : NULL; } // Changes the return type of WebPEncode* to more closely match Decode*. // This also makes it easier to wrap the output buffer in a native type rather // than dealing with the return pointer. // The additional parameters are to allow reuse of ReturnedBufferSize(), // unused2 and output_size will be used in this case. #define LOSSY_WRAPPER(FUNC) \ static uint8_t* wrap_##FUNC( \ const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ int width, int height, int stride, float quality_factor) { \ return EncodeLossy(rgb, width, height, stride, quality_factor, \ FUNC, output_size, unused2); \ } \ LOSSY_WRAPPER(WebPEncodeRGB) LOSSY_WRAPPER(WebPEncodeBGR) LOSSY_WRAPPER(WebPEncodeRGBA) LOSSY_WRAPPER(WebPEncodeBGRA) #undef LOSSY_WRAPPER #define LOSSLESS_WRAPPER(FUNC) \ static uint8_t* wrap_##FUNC( \ const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ int width, int height, int stride) { \ return EncodeLossless(rgb, width, height, stride, \ FUNC, output_size, unused2); \ } \ LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) #undef LOSSLESS_WRAPPER #include #if !defined(SWIG_NO_LLONG_MAX) # if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) # define LLONG_MAX __LONG_LONG_MAX__ # define LLONG_MIN (-LLONG_MAX - 1LL) # define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) # endif #endif SWIGINTERN int SWIG_AsVal_long (PyObject *obj, long* val) { if (PyInt_Check(obj)) { if (val) *val = PyInt_AsLong(obj); return SWIG_OK; } else if (PyLong_Check(obj)) { long v = PyLong_AsLong(obj); if (!PyErr_Occurred()) { if (val) *val = v; return SWIG_OK; } else { PyErr_Clear(); } } #ifdef SWIG_PYTHON_CAST_MODE { int dispatch = 0; long v = PyInt_AsLong(obj); if (!PyErr_Occurred()) { if (val) *val = v; return SWIG_AddCast(SWIG_OK); } else { PyErr_Clear(); } if (!dispatch) { double d; int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { if (val) *val = (long)(d); return res; } } } #endif return SWIG_TypeError; } SWIGINTERN int SWIG_AsVal_int (PyObject * obj, int *val) { long v; int res = SWIG_AsVal_long (obj, &v); if (SWIG_IsOK(res)) { if ((v < INT_MIN || v > INT_MAX)) { return SWIG_OverflowError; } else { if (val) *val = (int)(v); } } return res; } SWIGINTERN int SWIG_AsVal_float (PyObject * obj, float *val) { double v; int res = SWIG_AsVal_double (obj, &v); if (SWIG_IsOK(res)) { if ((v < -FLT_MAX || v > FLT_MAX)) { return SWIG_OverflowError; } else { if (val) *val = (float)(v); } } return res; } #ifdef __cplusplus extern "C" { #endif SWIGINTERN PyObject *_wrap_WebPGetDecoderVersion(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; int result; if (!PyArg_ParseTuple(args,(char *)":WebPGetDecoderVersion")) SWIG_fail; result = (int)WebPGetDecoderVersion(); resultobj = SWIG_From_int((int)(result)); return resultobj; fail: return NULL; } SWIGINTERN PyObject *_wrap_WebPGetInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int res1 ; char *buf1 = 0 ; size_t size1 = 0 ; int alloc1 = 0 ; int temp3 ; int res3 = SWIG_TMPOBJ ; int temp4 ; int res4 = SWIG_TMPOBJ ; PyObject * obj0 = 0 ; int result; arg3 = &temp3; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"O:WebPGetInfo",&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, &size1, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "WebPGetInfo" "', argument " "1"" of type '" "uint8_t const *""'"); } arg1 = (uint8_t *)(buf1); arg2 = (size_t)(size1 - 1); result = (int)WebPGetInfo((uint8_t const *)arg1,arg2,arg3,arg4); resultobj = SWIG_From_int((int)(result)); if (SWIG_IsTmpObj(res3)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg3))); } else { int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_int, new_flags)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return NULL; } SWIGINTERN PyObject *_wrap_WebPDecodeRGB(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int res1 ; char *buf1 = 0 ; size_t size1 = 0 ; int alloc1 = 0 ; int temp3 ; int res3 = SWIG_TMPOBJ ; int temp4 ; int res4 = SWIG_TMPOBJ ; PyObject * obj0 = 0 ; uint8_t *result = 0 ; arg3 = &temp3; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"O:WebPDecodeRGB",&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, &size1, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "WebPDecodeRGB" "', argument " "1"" of type '" "uint8_t const *""'"); } arg1 = (uint8_t *)(buf1); arg2 = (size_t)(size1 - 1); result = (uint8_t *)WebPDecodeRGB((uint8_t const *)arg1,arg2,arg3,arg4); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("WebPDecodeRGB", arg3, arg4)); } if (SWIG_IsTmpObj(res3)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg3))); } else { int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_int, new_flags)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); free(result); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return NULL; } SWIGINTERN PyObject *_wrap_WebPDecodeRGBA(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int res1 ; char *buf1 = 0 ; size_t size1 = 0 ; int alloc1 = 0 ; int temp3 ; int res3 = SWIG_TMPOBJ ; int temp4 ; int res4 = SWIG_TMPOBJ ; PyObject * obj0 = 0 ; uint8_t *result = 0 ; arg3 = &temp3; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"O:WebPDecodeRGBA",&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, &size1, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "WebPDecodeRGBA" "', argument " "1"" of type '" "uint8_t const *""'"); } arg1 = (uint8_t *)(buf1); arg2 = (size_t)(size1 - 1); result = (uint8_t *)WebPDecodeRGBA((uint8_t const *)arg1,arg2,arg3,arg4); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("WebPDecodeRGBA", arg3, arg4)); } if (SWIG_IsTmpObj(res3)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg3))); } else { int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_int, new_flags)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); free(result); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return NULL; } SWIGINTERN PyObject *_wrap_WebPDecodeARGB(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int res1 ; char *buf1 = 0 ; size_t size1 = 0 ; int alloc1 = 0 ; int temp3 ; int res3 = SWIG_TMPOBJ ; int temp4 ; int res4 = SWIG_TMPOBJ ; PyObject * obj0 = 0 ; uint8_t *result = 0 ; arg3 = &temp3; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"O:WebPDecodeARGB",&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, &size1, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "WebPDecodeARGB" "', argument " "1"" of type '" "uint8_t const *""'"); } arg1 = (uint8_t *)(buf1); arg2 = (size_t)(size1 - 1); result = (uint8_t *)WebPDecodeARGB((uint8_t const *)arg1,arg2,arg3,arg4); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("WebPDecodeARGB", arg3, arg4)); } if (SWIG_IsTmpObj(res3)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg3))); } else { int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_int, new_flags)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); free(result); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return NULL; } SWIGINTERN PyObject *_wrap_WebPDecodeBGR(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int res1 ; char *buf1 = 0 ; size_t size1 = 0 ; int alloc1 = 0 ; int temp3 ; int res3 = SWIG_TMPOBJ ; int temp4 ; int res4 = SWIG_TMPOBJ ; PyObject * obj0 = 0 ; uint8_t *result = 0 ; arg3 = &temp3; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"O:WebPDecodeBGR",&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, &size1, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "WebPDecodeBGR" "', argument " "1"" of type '" "uint8_t const *""'"); } arg1 = (uint8_t *)(buf1); arg2 = (size_t)(size1 - 1); result = (uint8_t *)WebPDecodeBGR((uint8_t const *)arg1,arg2,arg3,arg4); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("WebPDecodeBGR", arg3, arg4)); } if (SWIG_IsTmpObj(res3)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg3))); } else { int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_int, new_flags)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); free(result); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return NULL; } SWIGINTERN PyObject *_wrap_WebPDecodeBGRA(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int res1 ; char *buf1 = 0 ; size_t size1 = 0 ; int alloc1 = 0 ; int temp3 ; int res3 = SWIG_TMPOBJ ; int temp4 ; int res4 = SWIG_TMPOBJ ; PyObject * obj0 = 0 ; uint8_t *result = 0 ; arg3 = &temp3; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"O:WebPDecodeBGRA",&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, &size1, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "WebPDecodeBGRA" "', argument " "1"" of type '" "uint8_t const *""'"); } arg1 = (uint8_t *)(buf1); arg2 = (size_t)(size1 - 1); result = (uint8_t *)WebPDecodeBGRA((uint8_t const *)arg1,arg2,arg3,arg4); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("WebPDecodeBGRA", arg3, arg4)); } if (SWIG_IsTmpObj(res3)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg3))); } else { int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_int, new_flags)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); free(result); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); return NULL; } SWIGINTERN PyObject *_wrap_WebPGetEncoderVersion(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; int result; if (!PyArg_ParseTuple(args,(char *)":WebPGetEncoderVersion")) SWIG_fail; result = (int)WebPGetEncoderVersion(); resultobj = SWIG_From_int((int)(result)); return resultobj; fail: return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeRGB(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; float val8 ; int ecode8 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; PyObject * obj6 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:wrap_WebPEncodeRGB",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeRGB', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeRGB', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeRGB" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeRGB" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeRGB" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeRGB" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeRGB" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); ecode8 = SWIG_AsVal_float(obj6, &val8); if (!SWIG_IsOK(ecode8)) { SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "wrap_WebPEncodeRGB" "', argument " "8"" of type '" "float""'"); } arg8 = (float)(val8); result = (uint8_t *)wrap_WebPEncodeRGB((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeRGB", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeBGR(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; float val8 ; int ecode8 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; PyObject * obj6 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:wrap_WebPEncodeBGR",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeBGR', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeBGR', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeBGR" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeBGR" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeBGR" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeBGR" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeBGR" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); ecode8 = SWIG_AsVal_float(obj6, &val8); if (!SWIG_IsOK(ecode8)) { SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "wrap_WebPEncodeBGR" "', argument " "8"" of type '" "float""'"); } arg8 = (float)(val8); result = (uint8_t *)wrap_WebPEncodeBGR((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeBGR", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeRGBA(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; float val8 ; int ecode8 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; PyObject * obj6 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:wrap_WebPEncodeRGBA",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeRGBA', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeRGBA', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeRGBA" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeRGBA" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeRGBA" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeRGBA" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeRGBA" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); ecode8 = SWIG_AsVal_float(obj6, &val8); if (!SWIG_IsOK(ecode8)) { SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "wrap_WebPEncodeRGBA" "', argument " "8"" of type '" "float""'"); } arg8 = (float)(val8); result = (uint8_t *)wrap_WebPEncodeRGBA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeRGBA", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeBGRA(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; float val8 ; int ecode8 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; PyObject * obj6 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:wrap_WebPEncodeBGRA",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeBGRA', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeBGRA', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeBGRA" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeBGRA" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeBGRA" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeBGRA" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeBGRA" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); ecode8 = SWIG_AsVal_float(obj6, &val8); if (!SWIG_IsOK(ecode8)) { SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "wrap_WebPEncodeBGRA" "', argument " "8"" of type '" "float""'"); } arg8 = (float)(val8); result = (uint8_t *)wrap_WebPEncodeBGRA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeBGRA", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeLosslessRGB(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOO:wrap_WebPEncodeLosslessRGB",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeLosslessRGB', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeLosslessRGB', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessRGB" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessRGB" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeLosslessRGB" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeLosslessRGB" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeLosslessRGB" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); result = (uint8_t *)wrap_WebPEncodeLosslessRGB((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeLosslessRGB", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeLosslessBGR(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOO:wrap_WebPEncodeLosslessBGR",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeLosslessBGR', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeLosslessBGR', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessBGR" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessBGR" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeLosslessBGR" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeLosslessBGR" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeLosslessBGR" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); result = (uint8_t *)wrap_WebPEncodeLosslessBGR((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeLosslessBGR", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeLosslessRGBA(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOO:wrap_WebPEncodeLosslessRGBA",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeLosslessRGBA', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeLosslessRGBA', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessRGBA" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessRGBA" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeLosslessRGBA" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeLosslessRGBA" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeLosslessRGBA" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); result = (uint8_t *)wrap_WebPEncodeLosslessRGBA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeLosslessRGBA", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } SWIGINTERN PyObject *_wrap_wrap_WebPEncodeLosslessBGRA(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; Py_buffer rgb_buffer1 ; int temp2 ; int res2 = 0 ; int temp3 ; int res3 = 0 ; int temp4 ; int res4 = SWIG_TMPOBJ ; int val5 ; int ecode5 = 0 ; int val6 ; int ecode6 = 0 ; int val7 ; int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; uint8_t *result = 0 ; arg4 = &temp4; if (!PyArg_ParseTuple(args,(char *)"OOOOOO:wrap_WebPEncodeLosslessBGRA",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; { // NB: with Python < 2.6 the old style buffer protocol may be used: // Py_ssize_t unused; // PyObject_AsReadBuffer(obj0, (const void**)(&arg1), &unused); if (!PyObject_CheckBuffer(obj0)) { SWIG_exception_fail(SWIG_TypeError, "in method 'wrap_WebPEncodeLosslessBGRA', argument 1" " does not support the buffer interface"); } if (PyObject_GetBuffer(obj0, &rgb_buffer1, PyBUF_SIMPLE)) { SWIG_exception_fail(SWIG_RuntimeError, "in method 'wrap_WebPEncodeLosslessBGRA', unable to get buffer view"); } arg1 = (uint8_t *)rgb_buffer1.buf; } if (!(SWIG_IsOK((res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj1, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessBGRA" "', argument " "2"" of type '" "int""'"); } temp2 = (int)(val); arg2 = &temp2; res2 = SWIG_AddTmpMask(ecode); } if (!(SWIG_IsOK((res3 = SWIG_ConvertPtr(obj2,SWIG_as_voidptrptr(&arg3),SWIGTYPE_p_int,0))))) { int val; int ecode = SWIG_AsVal_int(obj2, &val); if (!SWIG_IsOK(ecode)) { SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "wrap_WebPEncodeLosslessBGRA" "', argument " "3"" of type '" "int""'"); } temp3 = (int)(val); arg3 = &temp3; res3 = SWIG_AddTmpMask(ecode); } ecode5 = SWIG_AsVal_int(obj3, &val5); if (!SWIG_IsOK(ecode5)) { SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "wrap_WebPEncodeLosslessBGRA" "', argument " "5"" of type '" "int""'"); } arg5 = (int)(val5); ecode6 = SWIG_AsVal_int(obj4, &val6); if (!SWIG_IsOK(ecode6)) { SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "wrap_WebPEncodeLosslessBGRA" "', argument " "6"" of type '" "int""'"); } arg6 = (int)(val6); ecode7 = SWIG_AsVal_int(obj5, &val7); if (!SWIG_IsOK(ecode7)) { SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "wrap_WebPEncodeLosslessBGRA" "', argument " "7"" of type '" "int""'"); } arg7 = (int)(val7); result = (uint8_t *)wrap_WebPEncodeLosslessBGRA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); { resultobj = PyString_FromStringAndSize( (const char*)result, (result == NULL) ? 0 : ReturnedBufferSize("wrap_WebPEncodeLosslessBGRA", arg3, arg4)); } if (SWIG_IsTmpObj(res4)) { resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg4))); } else { int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ; resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_int, new_flags)); } { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); free(result); return resultobj; fail: { PyBuffer_Release(&rgb_buffer1); } if (SWIG_IsNewObj(res2)) free((char*)arg2); if (SWIG_IsNewObj(res3)) free((char*)arg3); return NULL; } static PyMethodDef SwigMethods[] = { { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL}, { (char *)"WebPGetDecoderVersion", _wrap_WebPGetDecoderVersion, METH_VARARGS, (char *)"WebPGetDecoderVersion() -> int"}, { (char *)"WebPGetInfo", _wrap_WebPGetInfo, METH_VARARGS, (char *)"WebPGetInfo(uint8_t data) -> (width, height)"}, { (char *)"WebPDecodeRGB", _wrap_WebPDecodeRGB, METH_VARARGS, (char *)"WebPDecodeRGB(uint8_t data) -> (rgb, width, height)"}, { (char *)"WebPDecodeRGBA", _wrap_WebPDecodeRGBA, METH_VARARGS, (char *)"WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)"}, { (char *)"WebPDecodeARGB", _wrap_WebPDecodeARGB, METH_VARARGS, (char *)"WebPDecodeARGB(uint8_t data) -> (rgb, width, height)"}, { (char *)"WebPDecodeBGR", _wrap_WebPDecodeBGR, METH_VARARGS, (char *)"WebPDecodeBGR(uint8_t data) -> (rgb, width, height)"}, { (char *)"WebPDecodeBGRA", _wrap_WebPDecodeBGRA, METH_VARARGS, (char *)"WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)"}, { (char *)"WebPGetEncoderVersion", _wrap_WebPGetEncoderVersion, METH_VARARGS, (char *)"WebPGetEncoderVersion() -> int"}, { (char *)"wrap_WebPEncodeRGB", _wrap_wrap_WebPEncodeRGB, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeBGR", _wrap_wrap_WebPEncodeBGR, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeRGBA", _wrap_wrap_WebPEncodeRGBA, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeBGRA", _wrap_wrap_WebPEncodeBGRA, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeLosslessRGB", _wrap_wrap_WebPEncodeLosslessRGB, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeLosslessBGR", _wrap_wrap_WebPEncodeLosslessBGR, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeLosslessRGBA", _wrap_wrap_WebPEncodeLosslessRGBA, METH_VARARGS, (char *)"private, do not call directly."}, { (char *)"wrap_WebPEncodeLosslessBGRA", _wrap_wrap_WebPEncodeLosslessBGRA, METH_VARARGS, (char *)"private, do not call directly."}, { NULL, NULL, 0, NULL } }; /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "int *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_uint8_t = {"_p_uint8_t", "uint8_t *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { &_swigt__p_char, &_swigt__p_int, &_swigt__p_uint8_t, }; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_uint8_t[] = { {&_swigt__p_uint8_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { _swigc__p_char, _swigc__p_int, _swigc__p_uint8_t, }; /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ static swig_const_info swig_const_table[] = { {0, 0, 0, 0.0, 0, 0}}; #ifdef __cplusplus } #endif /* ----------------------------------------------------------------------------- * Type initialization: * This problem is tough by the requirement that no dynamic * memory is used. Also, since swig_type_info structures store pointers to * swig_cast_info structures and swig_cast_info structures store pointers back * to swig_type_info structures, we need some lookup code at initialization. * The idea is that swig generates all the structures that are needed. * The runtime then collects these partially filled structures. * The SWIG_InitializeModule function takes these initial arrays out of * swig_module, and does all the lookup, filling in the swig_module.types * array with the correct data and linking the correct swig_cast_info * structures together. * * The generated swig_type_info structures are assigned staticly to an initial * array. We just loop through that array, and handle each type individually. * First we lookup if this type has been already loaded, and if so, use the * loaded structure instead of the generated one. Then we have to fill in the * cast linked list. The cast data is initially stored in something like a * two-dimensional array. Each row corresponds to a type (there are the same * number of rows as there are in the swig_type_initial array). Each entry in * a column is one of the swig_cast_info structures for that type. * The cast_initial array is actually an array of arrays, because each row has * a variable number of columns. So to actually build the cast linked list, * we find the array of casts associated with the type, and loop through it * adding the casts to the list. The one last trick we need to do is making * sure the type pointer in the swig_cast_info struct is correct. * * First off, we lookup the cast->type name to see if it is already loaded. * There are three cases to handle: * 1) If the cast->type has already been loaded AND the type we are adding * casting info to has not been loaded (it is in this module), THEN we * replace the cast->type pointer with the type pointer that has already * been loaded. * 2) If BOTH types (the one we are adding casting info to, and the * cast->type) are loaded, THEN the cast info has already been loaded by * the previous module so we just ignore it. * 3) Finally, if cast->type has not already been loaded, then we add that * swig_cast_info to the linked list (because the cast->type) pointer will * be correct. * ----------------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" { #if 0 } /* c-mode */ #endif #endif #if 0 #define SWIGRUNTIME_DEBUG #endif SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; int found, init; clientdata = clientdata; /* check to see if the circular list has been setup, if not, set it up */ if (swig_module.next==0) { /* Initialize the swig_module */ swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; init = 1; } else { init = 0; } /* Try and load any already created modules */ module_head = SWIG_GetModule(clientdata); if (!module_head) { /* This is the first module loaded for this interpreter */ /* so set the swig module into the interpreter */ SWIG_SetModule(clientdata, &swig_module); module_head = &swig_module; } else { /* the interpreter has loaded a SWIG module, but has it loaded this one? */ found=0; iter=module_head; do { if (iter==&swig_module) { found=1; break; } iter=iter->next; } while (iter!= module_head); /* if the is found in the list, then all is done and we may leave */ if (found) return; /* otherwise we must add out module into the list */ swig_module.next = module_head->next; module_head->next = &swig_module; } /* When multiple interpeters are used, a module could have already been initialized in a different interpreter, but not yet have a pointer in this interpreter. In this case, we do not want to continue adding types... everything should be set up already */ if (init == 0) return; /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); #endif for (i = 0; i < swig_module.size; ++i) { swig_type_info *type = 0; swig_type_info *ret; swig_cast_info *cast; #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); #endif /* if there is another module already loaded */ if (swig_module.next != &swig_module) { type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); } if (type) { /* Overwrite clientdata field */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: found type %s\n", type->name); #endif if (swig_module.type_initial[i]->clientdata) { type->clientdata = swig_module.type_initial[i]->clientdata; #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); #endif } } else { type = swig_module.type_initial[i]; } /* Insert casting types */ cast = swig_module.cast_initial[i]; while (cast->type) { /* Don't need to add information already in the list */ ret = 0; #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); #endif if (swig_module.next != &swig_module) { ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); #ifdef SWIGRUNTIME_DEBUG if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); #endif } if (ret) { if (type == swig_module.type_initial[i]) { #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: skip old type %s\n", ret->name); #endif cast->type = ret; ret = 0; } else { /* Check for casting already in the list */ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); #ifdef SWIGRUNTIME_DEBUG if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); #endif if (!ocast) ret = 0; } } if (!ret) { #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); #endif if (type->cast) { type->cast->prev = cast; cast->next = type->cast; } type->cast = cast; } cast++; } /* Set entry in modules->types array equal to the type */ swig_module.types[i] = type; } swig_module.types[i] = 0; #ifdef SWIGRUNTIME_DEBUG printf("**** SWIG_InitializeModule: Cast List ******\n"); for (i = 0; i < swig_module.size; ++i) { int j = 0; swig_cast_info *cast = swig_module.cast_initial[i]; printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); while (cast->type) { printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); cast++; ++j; } printf("---- Total casts: %d\n",j); } printf("**** SWIG_InitializeModule: Cast List ******\n"); #endif } /* This function will propagate the clientdata field of type to * any new swig_type_info structures that have been added into the list * of equivalent types. It is like calling * SWIG_TypeClientData(type, clientdata) a second time. */ SWIGRUNTIME void SWIG_PropagateClientData(void) { size_t i; swig_cast_info *equiv; static int init_run = 0; if (init_run) return; init_run = 1; for (i = 0; i < swig_module.size; i++) { if (swig_module.types[i]->clientdata) { equiv = swig_module.types[i]->cast; while (equiv) { if (!equiv->converter) { if (equiv->type && !equiv->type->clientdata) SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); } equiv = equiv->next; } } } } #ifdef __cplusplus #if 0 { /* c-mode */ #endif } #endif #ifdef __cplusplus extern "C" { #endif /* Python-specific SWIG API */ #define SWIG_newvarlink() SWIG_Python_newvarlink() #define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) #define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) /* ----------------------------------------------------------------------------- * global variable support code. * ----------------------------------------------------------------------------- */ typedef struct swig_globalvar { char *name; /* Name of global variable */ PyObject *(*get_attr)(void); /* Return the current value */ int (*set_attr)(PyObject *); /* Set the value */ struct swig_globalvar *next; } swig_globalvar; typedef struct swig_varlinkobject { PyObject_HEAD swig_globalvar *vars; } swig_varlinkobject; SWIGINTERN PyObject * swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { #if PY_VERSION_HEX >= 0x03000000 return PyUnicode_InternFromString(""); #else return PyString_FromString(""); #endif } SWIGINTERN PyObject * swig_varlink_str(swig_varlinkobject *v) { #if PY_VERSION_HEX >= 0x03000000 PyObject *str = PyUnicode_InternFromString("("); PyObject *tail; PyObject *joined; swig_globalvar *var; for (var = v->vars; var; var=var->next) { tail = PyUnicode_FromString(var->name); joined = PyUnicode_Concat(str, tail); Py_DecRef(str); Py_DecRef(tail); str = joined; if (var->next) { tail = PyUnicode_InternFromString(", "); joined = PyUnicode_Concat(str, tail); Py_DecRef(str); Py_DecRef(tail); str = joined; } } tail = PyUnicode_InternFromString(")"); joined = PyUnicode_Concat(str, tail); Py_DecRef(str); Py_DecRef(tail); str = joined; #else PyObject *str = PyString_FromString("("); swig_globalvar *var; for (var = v->vars; var; var=var->next) { PyString_ConcatAndDel(&str,PyString_FromString(var->name)); if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); } PyString_ConcatAndDel(&str,PyString_FromString(")")); #endif return str; } SWIGINTERN int swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { char *tmp; PyObject *str = swig_varlink_str(v); fprintf(fp,"Swig global variables "); fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str)); SWIG_Python_str_DelForPy3(tmp); Py_DECREF(str); return 0; } SWIGINTERN void swig_varlink_dealloc(swig_varlinkobject *v) { swig_globalvar *var = v->vars; while (var) { swig_globalvar *n = var->next; free(var->name); free(var); var = n; } } SWIGINTERN PyObject * swig_varlink_getattr(swig_varlinkobject *v, char *n) { PyObject *res = NULL; swig_globalvar *var = v->vars; while (var) { if (strcmp(var->name,n) == 0) { res = (*var->get_attr)(); break; } var = var->next; } if (res == NULL && !PyErr_Occurred()) { PyErr_SetString(PyExc_NameError,"Unknown C global variable"); } return res; } SWIGINTERN int swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { int res = 1; swig_globalvar *var = v->vars; while (var) { if (strcmp(var->name,n) == 0) { res = (*var->set_attr)(p); break; } var = var->next; } if (res == 1 && !PyErr_Occurred()) { PyErr_SetString(PyExc_NameError,"Unknown C global variable"); } return res; } SWIGINTERN PyTypeObject* swig_varlink_type(void) { static char varlink__doc__[] = "Swig var link object"; static PyTypeObject varlink_type; static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX >= 0x03000000 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ #endif (char *)"swigvarlink", /* tp_name */ sizeof(swig_varlinkobject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) swig_varlink_dealloc, /* tp_dealloc */ (printfunc) swig_varlink_print, /* tp_print */ (getattrfunc) swig_varlink_getattr, /* tp_getattr */ (setattrfunc) swig_varlink_setattr, /* tp_setattr */ 0, /* tp_compare */ (reprfunc) swig_varlink_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ (reprfunc) swig_varlink_str, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ varlink__doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ #if PY_VERSION_HEX >= 0x02020000 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ #endif #if PY_VERSION_HEX >= 0x02030000 0, /* tp_del */ #endif #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version */ #endif #ifdef COUNT_ALLOCS 0,0,0,0 /* tp_alloc -> tp_next */ #endif }; varlink_type = tmp; type_init = 1; #if PY_VERSION_HEX < 0x02020000 varlink_type.ob_type = &PyType_Type; #else if (PyType_Ready(&varlink_type) < 0) return NULL; #endif } return &varlink_type; } /* Create a variable linking object for use later */ SWIGINTERN PyObject * SWIG_Python_newvarlink(void) { swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); if (result) { result->vars = 0; } return ((PyObject*) result); } SWIGINTERN void SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { swig_varlinkobject *v = (swig_varlinkobject *) p; swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); if (gv) { size_t size = strlen(name)+1; gv->name = (char *)malloc(size); if (gv->name) { strncpy(gv->name,name,size); gv->get_attr = get_attr; gv->set_attr = set_attr; gv->next = v->vars; } } v->vars = gv; } SWIGINTERN PyObject * SWIG_globals(void) { static PyObject *_SWIG_globals = 0; if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); return _SWIG_globals; } /* ----------------------------------------------------------------------------- * constants/methods manipulation * ----------------------------------------------------------------------------- */ /* Install Constants */ SWIGINTERN void SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { PyObject *obj = 0; size_t i; for (i = 0; constants[i].type; ++i) { switch(constants[i].type) { case SWIG_PY_POINTER: obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); break; case SWIG_PY_BINARY: obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); break; default: obj = 0; break; } if (obj) { PyDict_SetItemString(d, constants[i].name, obj); Py_DECREF(obj); } } } /* -----------------------------------------------------------------------------*/ /* Fix SwigMethods to carry the callback ptrs when needed */ /* -----------------------------------------------------------------------------*/ SWIGINTERN void SWIG_Python_FixMethods(PyMethodDef *methods, swig_const_info *const_table, swig_type_info **types, swig_type_info **types_initial) { size_t i; for (i = 0; methods[i].ml_name; ++i) { const char *c = methods[i].ml_doc; if (c && (c = strstr(c, "swig_ptr: "))) { int j; swig_const_info *ci = 0; const char *name = c + 10; for (j = 0; const_table[j].type; ++j) { if (strncmp(const_table[j].name, name, strlen(const_table[j].name)) == 0) { ci = &(const_table[j]); break; } } if (ci) { void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; if (ptr) { size_t shift = (ci->ptype) - types; swig_type_info *ty = types_initial[shift]; size_t ldoc = (c - methods[i].ml_doc); size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; char *ndoc = (char*)malloc(ldoc + lptr + 10); if (ndoc) { char *buff = ndoc; strncpy(buff, methods[i].ml_doc, ldoc); buff += ldoc; strncpy(buff, "swig_ptr: ", 10); buff += 10; SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); methods[i].ml_doc = ndoc; } } } } } } #ifdef __cplusplus } #endif /* -----------------------------------------------------------------------------* * Partial Init method * -----------------------------------------------------------------------------*/ #ifdef __cplusplus extern "C" #endif SWIGEXPORT #if PY_VERSION_HEX >= 0x03000000 PyObject* #else void #endif SWIG_init(void) { PyObject *m, *d, *md; #if PY_VERSION_HEX >= 0x03000000 static struct PyModuleDef SWIG_module = { # if PY_VERSION_HEX >= 0x03020000 PyModuleDef_HEAD_INIT, # else { PyObject_HEAD_INIT(NULL) NULL, /* m_init */ 0, /* m_index */ NULL, /* m_copy */ }, # endif (char *) SWIG_name, NULL, -1, SwigMethods, NULL, NULL, NULL, NULL }; #endif #if defined(SWIGPYTHON_BUILTIN) static SwigPyClientData SwigPyObject_clientdata = { 0, 0, 0, 0, 0, 0, 0 }; static PyGetSetDef this_getset_def = { (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL }; static SwigPyGetSet thisown_getset_closure = { (PyCFunction) SwigPyObject_own, (PyCFunction) SwigPyObject_own }; static PyGetSetDef thisown_getset_def = { (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure }; PyObject *metatype_args; PyTypeObject *builtin_pytype; int builtin_base_count; swig_type_info *builtin_basetype; PyObject *tuple; PyGetSetDescrObject *static_getset; PyTypeObject *metatype; SwigPyClientData *cd; PyObject *public_interface, *public_symbol; PyObject *this_descr; PyObject *thisown_descr; int i; (void)builtin_pytype; (void)builtin_base_count; (void)builtin_basetype; (void)tuple; (void)static_getset; /* metatype is used to implement static member variables. */ metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type); assert(metatype_args); metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL); assert(metatype); Py_DECREF(metatype_args); metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro; assert(PyType_Ready(metatype) >= 0); #endif /* Fix SwigMethods to carry the callback ptrs when needed */ SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); #if PY_VERSION_HEX >= 0x03000000 m = PyModule_Create(&SWIG_module); #else m = Py_InitModule((char *) SWIG_name, SwigMethods); #endif md = d = PyModule_GetDict(m); SWIG_InitializeModule(0); #ifdef SWIGPYTHON_BUILTIN SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject"); assert(SwigPyObject_stype); cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; if (!cd) { SwigPyObject_stype->clientdata = &SwigPyObject_clientdata; SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce(); } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) { PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules."); # if PY_VERSION_HEX >= 0x03000000 return NULL; # else return; # endif } /* All objects have a 'this' attribute */ this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def); (void)this_descr; /* All objects have a 'thisown' attribute */ thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def); (void)thisown_descr; public_interface = PyList_New(0); public_symbol = 0; (void)public_symbol; PyDict_SetItemString(md, "__all__", public_interface); Py_DECREF(public_interface); for (i = 0; SwigMethods[i].ml_name != NULL; ++i) SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name); for (i = 0; swig_const_table[i].name != 0; ++i) SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name); #endif SWIG_InstallConstants(d,swig_const_table); #if PY_VERSION_HEX >= 0x03000000 return m; #else return; #endif } libwebp-0.4.0/swig/libwebp.go0000644000014400001440000000232312255002107012765 0ustar /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). * Version 2.0.10 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make * changes to this file unless you know what you are doing--modify the SWIG * interface file instead. * ----------------------------------------------------------------------------- */ package libwebp import _ "runtime/cgo" import "unsafe" type _ unsafe.Pointer type _swig_fnptr *byte type _swig_memberptr *byte //extern libwebpSwigCgocall func SwigCgocall() //extern libwebpSwigCgocallDone func SwigCgocallDone() //extern libwebpSwigCgocallBack func SwigCgocallBack() //extern libwebpSwigCgocallBackDone func SwigCgocallBackDone() func WebPGetDecoderVersion() int func Wrapped_WebPGetInfo(string, []int, []int) int // WebPGetInfo has 2 output parameters, provide a version in the more natural // go idiom: func WebPGetInfo(webp []byte) (ok bool, width int, height int) { w := []int{0} h := []int{0} ok = Wrapped_WebPGetInfo(string(webp), w, h) != 0 width = w[0] height = h[0] return } libwebp-0.4.0/swig/libwebp_gc.c0000644000014400001440000000267412255002107013264 0ustar /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). * Version 2.0.10 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make * changes to this file unless you know what you are doing--modify the SWIG * interface file instead. * ----------------------------------------------------------------------------- */ /* This file should be compiled with 6c/8c. */ #pragma dynimport _ _ "libwebp_go.so" #include "runtime.h" #include "cgocall.h" #ifdef _64BIT #define SWIG_PARM_SIZE 8 #else #define SWIG_PARM_SIZE 4 #endif #pragma dynimport _wrap_WebPGetDecoderVersion _wrap_WebPGetDecoderVersion "" extern void (*_wrap_WebPGetDecoderVersion)(void*); static void (*x_wrap_WebPGetDecoderVersion)(void*) = _wrap_WebPGetDecoderVersion; void ·WebPGetDecoderVersion(struct { uint8 x[SWIG_PARM_SIZE]; } p) { runtime·cgocall(x_wrap_WebPGetDecoderVersion, &p); } #pragma dynimport _wrap_wrapped_WebPGetInfo _wrap_wrapped_WebPGetInfo "" extern void (*_wrap_wrapped_WebPGetInfo)(void*); static void (*x_wrap_wrapped_WebPGetInfo)(void*) = _wrap_wrapped_WebPGetInfo; void ·Wrapped_WebPGetInfo(struct { uint8 x[(2 * SWIG_PARM_SIZE) + (3 * SWIG_PARM_SIZE) + (3 * SWIG_PARM_SIZE) + SWIG_PARM_SIZE]; } p) { runtime·cgocall(x_wrap_wrapped_WebPGetInfo, &p); } libwebp-0.4.0/swig/libwebp.py0000644000014400001440000001471512255002107013020 0ustar # This file was automatically generated by SWIG (http://www.swig.org). # Version 2.0.4 # # Do not make changes to this file unless you know what you are doing--modify # the SWIG interface file instead. from sys import version_info if version_info >= (2,6,0): def swig_import_helper(): from os.path import dirname import imp fp = None try: fp, pathname, description = imp.find_module('_libwebp', [dirname(__file__)]) except ImportError: import _libwebp return _libwebp if fp is not None: try: _mod = imp.load_module('_libwebp', fp, pathname, description) finally: fp.close() return _mod _libwebp = swig_import_helper() del swig_import_helper else: import _libwebp del version_info try: _swig_property = property except NameError: pass # Python < 2.2 doesn't have 'property'. def _swig_setattr_nondynamic(self,class_type,name,value,static=1): if (name == "thisown"): return self.this.own(value) if (name == "this"): if type(value).__name__ == 'SwigPyObject': self.__dict__[name] = value return method = class_type.__swig_setmethods__.get(name,None) if method: return method(self,value) if (not static): self.__dict__[name] = value else: raise AttributeError("You cannot add attributes to %s" % self) def _swig_setattr(self,class_type,name,value): return _swig_setattr_nondynamic(self,class_type,name,value,0) def _swig_getattr(self,class_type,name): if (name == "thisown"): return self.this.own() method = class_type.__swig_getmethods__.get(name,None) if method: return method(self) raise AttributeError(name) def _swig_repr(self): try: strthis = "proxy of " + self.this.__repr__() except: strthis = "" return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) try: _object = object _newclass = 1 except AttributeError: class _object : pass _newclass = 0 def WebPGetDecoderVersion(): """WebPGetDecoderVersion() -> int""" return _libwebp.WebPGetDecoderVersion() def WebPGetInfo(*args): """WebPGetInfo(uint8_t data) -> (width, height)""" return _libwebp.WebPGetInfo(*args) def WebPDecodeRGB(*args): """WebPDecodeRGB(uint8_t data) -> (rgb, width, height)""" return _libwebp.WebPDecodeRGB(*args) def WebPDecodeRGBA(*args): """WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)""" return _libwebp.WebPDecodeRGBA(*args) def WebPDecodeARGB(*args): """WebPDecodeARGB(uint8_t data) -> (rgb, width, height)""" return _libwebp.WebPDecodeARGB(*args) def WebPDecodeBGR(*args): """WebPDecodeBGR(uint8_t data) -> (rgb, width, height)""" return _libwebp.WebPDecodeBGR(*args) def WebPDecodeBGRA(*args): """WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)""" return _libwebp.WebPDecodeBGRA(*args) def WebPGetEncoderVersion(): """WebPGetEncoderVersion() -> int""" return _libwebp.WebPGetEncoderVersion() def wrap_WebPEncodeRGB(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeRGB(*args) def wrap_WebPEncodeBGR(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeBGR(*args) def wrap_WebPEncodeRGBA(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeRGBA(*args) def wrap_WebPEncodeBGRA(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeBGRA(*args) def wrap_WebPEncodeLosslessRGB(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeLosslessRGB(*args) def wrap_WebPEncodeLosslessBGR(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeLosslessBGR(*args) def wrap_WebPEncodeLosslessRGBA(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeLosslessRGBA(*args) def wrap_WebPEncodeLosslessBGRA(*args): """private, do not call directly.""" return _libwebp.wrap_WebPEncodeLosslessBGRA(*args) _UNUSED = 1 def WebPEncodeRGB(rgb, width, height, stride, quality_factor): """WebPEncodeRGB(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" webp = wrap_WebPEncodeRGB( rgb, _UNUSED, _UNUSED, width, height, stride, quality_factor) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeRGBA(rgb, width, height, stride, quality_factor): """WebPEncodeRGBA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" webp = wrap_WebPEncodeRGBA( rgb, _UNUSED, _UNUSED, width, height, stride, quality_factor) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeBGR(rgb, width, height, stride, quality_factor): """WebPEncodeBGR(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" webp = wrap_WebPEncodeBGR( rgb, _UNUSED, _UNUSED, width, height, stride, quality_factor) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeBGRA(rgb, width, height, stride, quality_factor): """WebPEncodeBGRA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" webp = wrap_WebPEncodeBGRA( rgb, _UNUSED, _UNUSED, width, height, stride, quality_factor) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeLosslessRGB(rgb, width, height, stride): """WebPEncodeLosslessRGB(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" webp = wrap_WebPEncodeLosslessRGB(rgb, _UNUSED, _UNUSED, width, height, stride) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeLosslessRGBA(rgb, width, height, stride): """WebPEncodeLosslessRGBA(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" webp = wrap_WebPEncodeLosslessRGBA(rgb, _UNUSED, _UNUSED, width, height, stride) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeLosslessBGR(rgb, width, height, stride): """WebPEncodeLosslessBGR(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" webp = wrap_WebPEncodeLosslessBGR(rgb, _UNUSED, _UNUSED, width, height, stride) if len(webp[0]) == 0: return None return webp[0] def WebPEncodeLosslessBGRA(rgb, width, height, stride): """WebPEncodeLosslessBGRA(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" webp = wrap_WebPEncodeLosslessBGRA(rgb, _UNUSED, _UNUSED, width, height, stride) if len(webp[0]) == 0: return None return webp[0] # This file is compatible with both classic and new-style classes. libwebp-0.4.0/swig/libwebp_java_wrap.c0000644000014400001440000015064112255002107014643 0ustar /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). * Version 2.0.4 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make * changes to this file unless you know what you are doing--modify the SWIG * interface file instead. * ----------------------------------------------------------------------------- */ #define SWIGJAVA /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. * ----------------------------------------------------------------------------- */ /* template workaround for compilers that cannot correctly implement the C++ standard */ #ifndef SWIGTEMPLATEDISAMBIGUATOR # if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) # define SWIGTEMPLATEDISAMBIGUATOR template # elif defined(__HP_aCC) /* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ /* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ # define SWIGTEMPLATEDISAMBIGUATOR template # else # define SWIGTEMPLATEDISAMBIGUATOR # endif #endif /* inline attribute */ #ifndef SWIGINLINE # if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) # define SWIGINLINE inline # else # define SWIGINLINE # endif #endif /* attribute recognised by some compilers to avoid 'unused' warnings */ #ifndef SWIGUNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define SWIGUNUSED __attribute__ ((__unused__)) # else # define SWIGUNUSED # endif # elif defined(__ICC) # define SWIGUNUSED __attribute__ ((__unused__)) # else # define SWIGUNUSED # endif #endif #ifndef SWIG_MSC_UNSUPPRESS_4505 # if defined(_MSC_VER) # pragma warning(disable : 4505) /* unreferenced local function has been removed */ # endif #endif #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) # else # define SWIGUNUSEDPARM(p) p SWIGUNUSED # endif #endif /* internal SWIG method */ #ifndef SWIGINTERN # define SWIGINTERN static SWIGUNUSED #endif /* internal inline SWIG method */ #ifndef SWIGINTERNINLINE # define SWIGINTERNINLINE SWIGINTERN SWIGINLINE #endif /* exporting methods */ #if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) # ifndef GCC_HASCLASSVISIBILITY # define GCC_HASCLASSVISIBILITY # endif #endif #ifndef SWIGEXPORT # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # if defined(STATIC_LINKED) # define SWIGEXPORT # else # define SWIGEXPORT __declspec(dllexport) # endif # else # if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) # define SWIGEXPORT __attribute__ ((visibility("default"))) # else # define SWIGEXPORT # endif # endif #endif /* calling conventions for Windows */ #ifndef SWIGSTDCALL # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # define SWIGSTDCALL __stdcall # else # define SWIGSTDCALL # endif #endif /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) # define _CRT_SECURE_NO_DEPRECATE #endif /* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ #if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) # define _SCL_SECURE_NO_DEPRECATE #endif /* Fix for jlong on some versions of gcc on Windows */ #if defined(__GNUC__) && !defined(__INTEL_COMPILER) typedef long long __int64; #endif /* Fix for jlong on 64-bit x86 Solaris */ #if defined(__x86_64) # ifdef _LP64 # undef _LP64 # endif #endif #include #include #include /* Support for throwing Java exceptions */ typedef enum { SWIG_JavaOutOfMemoryError = 1, SWIG_JavaIOException, SWIG_JavaRuntimeException, SWIG_JavaIndexOutOfBoundsException, SWIG_JavaArithmeticException, SWIG_JavaIllegalArgumentException, SWIG_JavaNullPointerException, SWIG_JavaDirectorPureVirtual, SWIG_JavaUnknownError } SWIG_JavaExceptionCodes; typedef struct { SWIG_JavaExceptionCodes code; const char *java_exception; } SWIG_JavaExceptions_t; static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { jclass excep; static const SWIG_JavaExceptions_t java_exceptions[] = { { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, { SWIG_JavaIOException, "java/io/IOException" }, { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, { SWIG_JavaUnknownError, "java/lang/UnknownError" }, { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } }; const SWIG_JavaExceptions_t *except_ptr = java_exceptions; while (except_ptr->code != code && except_ptr->code) except_ptr++; (*jenv)->ExceptionClear(jenv); excep = (*jenv)->FindClass(jenv, except_ptr->java_exception); if (excep) (*jenv)->ThrowNew(jenv, excep, msg); } /* Contract support */ #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else /* Errors in SWIG */ #define SWIG_UnknownError -1 #define SWIG_IOError -2 #define SWIG_RuntimeError -3 #define SWIG_IndexError -4 #define SWIG_TypeError -5 #define SWIG_DivisionByZero -6 #define SWIG_OverflowError -7 #define SWIG_SyntaxError -8 #define SWIG_ValueError -9 #define SWIG_SystemError -10 #define SWIG_AttributeError -11 #define SWIG_MemoryError -12 #define SWIG_NullReferenceError -13 SWIGINTERN void SWIG_JavaException(JNIEnv *jenv, int code, const char *msg) { SWIG_JavaExceptionCodes exception_code = SWIG_JavaUnknownError; switch(code) { case SWIG_MemoryError: exception_code = SWIG_JavaOutOfMemoryError; break; case SWIG_IOError: exception_code = SWIG_JavaIOException; break; case SWIG_SystemError: case SWIG_RuntimeError: exception_code = SWIG_JavaRuntimeException; break; case SWIG_OverflowError: case SWIG_IndexError: exception_code = SWIG_JavaIndexOutOfBoundsException; break; case SWIG_DivisionByZero: exception_code = SWIG_JavaArithmeticException; break; case SWIG_SyntaxError: case SWIG_ValueError: case SWIG_TypeError: exception_code = SWIG_JavaIllegalArgumentException; break; case SWIG_UnknownError: default: exception_code = SWIG_JavaUnknownError; break; } SWIG_JavaThrowException(jenv, exception_code, msg); } #if defined(SWIG_NOINCLUDE) || defined(SWIG_NOARRAYS) int SWIG_JavaArrayInSchar (JNIEnv *jenv, jbyte **jarr, signed char **carr, jbyteArray input); void SWIG_JavaArrayArgoutSchar (JNIEnv *jenv, jbyte *jarr, signed char *carr, jbyteArray input); jbyteArray SWIG_JavaArrayOutSchar (JNIEnv *jenv, signed char *result, jsize sz); int SWIG_JavaArrayInUchar (JNIEnv *jenv, jshort **jarr, unsigned char **carr, jshortArray input); void SWIG_JavaArrayArgoutUchar (JNIEnv *jenv, jshort *jarr, unsigned char *carr, jshortArray input); jshortArray SWIG_JavaArrayOutUchar (JNIEnv *jenv, unsigned char *result, jsize sz); int SWIG_JavaArrayInShort (JNIEnv *jenv, jshort **jarr, short **carr, jshortArray input); void SWIG_JavaArrayArgoutShort (JNIEnv *jenv, jshort *jarr, short *carr, jshortArray input); jshortArray SWIG_JavaArrayOutShort (JNIEnv *jenv, short *result, jsize sz); int SWIG_JavaArrayInUshort (JNIEnv *jenv, jint **jarr, unsigned short **carr, jintArray input); void SWIG_JavaArrayArgoutUshort (JNIEnv *jenv, jint *jarr, unsigned short *carr, jintArray input); jintArray SWIG_JavaArrayOutUshort (JNIEnv *jenv, unsigned short *result, jsize sz); int SWIG_JavaArrayInInt (JNIEnv *jenv, jint **jarr, int **carr, jintArray input); void SWIG_JavaArrayArgoutInt (JNIEnv *jenv, jint *jarr, int *carr, jintArray input); jintArray SWIG_JavaArrayOutInt (JNIEnv *jenv, int *result, jsize sz); int SWIG_JavaArrayInUint (JNIEnv *jenv, jlong **jarr, unsigned int **carr, jlongArray input); void SWIG_JavaArrayArgoutUint (JNIEnv *jenv, jlong *jarr, unsigned int *carr, jlongArray input); jlongArray SWIG_JavaArrayOutUint (JNIEnv *jenv, unsigned int *result, jsize sz); int SWIG_JavaArrayInLong (JNIEnv *jenv, jint **jarr, long **carr, jintArray input); void SWIG_JavaArrayArgoutLong (JNIEnv *jenv, jint *jarr, long *carr, jintArray input); jintArray SWIG_JavaArrayOutLong (JNIEnv *jenv, long *result, jsize sz); int SWIG_JavaArrayInUlong (JNIEnv *jenv, jlong **jarr, unsigned long **carr, jlongArray input); void SWIG_JavaArrayArgoutUlong (JNIEnv *jenv, jlong *jarr, unsigned long *carr, jlongArray input); jlongArray SWIG_JavaArrayOutUlong (JNIEnv *jenv, unsigned long *result, jsize sz); int SWIG_JavaArrayInLonglong (JNIEnv *jenv, jlong **jarr, jlong **carr, jlongArray input); void SWIG_JavaArrayArgoutLonglong (JNIEnv *jenv, jlong *jarr, jlong *carr, jlongArray input); jlongArray SWIG_JavaArrayOutLonglong (JNIEnv *jenv, jlong *result, jsize sz); int SWIG_JavaArrayInFloat (JNIEnv *jenv, jfloat **jarr, float **carr, jfloatArray input); void SWIG_JavaArrayArgoutFloat (JNIEnv *jenv, jfloat *jarr, float *carr, jfloatArray input); jfloatArray SWIG_JavaArrayOutFloat (JNIEnv *jenv, float *result, jsize sz); int SWIG_JavaArrayInDouble (JNIEnv *jenv, jdouble **jarr, double **carr, jdoubleArray input); void SWIG_JavaArrayArgoutDouble (JNIEnv *jenv, jdouble *jarr, double *carr, jdoubleArray input); jdoubleArray SWIG_JavaArrayOutDouble (JNIEnv *jenv, double *result, jsize sz); #else /* signed char[] support */ int SWIG_JavaArrayInSchar (JNIEnv *jenv, jbyte **jarr, signed char **carr, jbyteArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetByteArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (signed char*) calloc(sz, sizeof(signed char)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseByteArrayElements(jenv, input, jarr, 0); } jbyteArray SWIG_JavaArrayOutSchar (JNIEnv *jenv, signed char *result, jsize sz) { jbyte *arr; int i; jbyteArray jresult = (*jenv)->NewByteArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetByteArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseByteArrayElements(jenv, jresult, arr, 0); return jresult; } /* unsigned char[] support */ int SWIG_JavaArrayInUchar (JNIEnv *jenv, jshort **jarr, unsigned char **carr, jshortArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetShortArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (unsigned char*) calloc(sz, sizeof(unsigned char)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseShortArrayElements(jenv, input, jarr, 0); } jshortArray SWIG_JavaArrayOutUchar (JNIEnv *jenv, unsigned char *result, jsize sz) { jshort *arr; int i; jshortArray jresult = (*jenv)->NewShortArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetShortArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseShortArrayElements(jenv, jresult, arr, 0); return jresult; } /* short[] support */ int SWIG_JavaArrayInShort (JNIEnv *jenv, jshort **jarr, short **carr, jshortArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetShortArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (short*) calloc(sz, sizeof(short)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseShortArrayElements(jenv, input, jarr, 0); } jshortArray SWIG_JavaArrayOutShort (JNIEnv *jenv, short *result, jsize sz) { jshort *arr; int i; jshortArray jresult = (*jenv)->NewShortArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetShortArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseShortArrayElements(jenv, jresult, arr, 0); return jresult; } /* unsigned short[] support */ int SWIG_JavaArrayInUshort (JNIEnv *jenv, jint **jarr, unsigned short **carr, jintArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetIntArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (unsigned short*) calloc(sz, sizeof(unsigned short)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseIntArrayElements(jenv, input, jarr, 0); } jintArray SWIG_JavaArrayOutUshort (JNIEnv *jenv, unsigned short *result, jsize sz) { jint *arr; int i; jintArray jresult = (*jenv)->NewIntArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetIntArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseIntArrayElements(jenv, jresult, arr, 0); return jresult; } /* int[] support */ int SWIG_JavaArrayInInt (JNIEnv *jenv, jint **jarr, int **carr, jintArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetIntArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (int*) calloc(sz, sizeof(int)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseIntArrayElements(jenv, input, jarr, 0); } jintArray SWIG_JavaArrayOutInt (JNIEnv *jenv, int *result, jsize sz) { jint *arr; int i; jintArray jresult = (*jenv)->NewIntArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetIntArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseIntArrayElements(jenv, jresult, arr, 0); return jresult; } /* unsigned int[] support */ int SWIG_JavaArrayInUint (JNIEnv *jenv, jlong **jarr, unsigned int **carr, jlongArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetLongArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (unsigned int*) calloc(sz, sizeof(unsigned int)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseLongArrayElements(jenv, input, jarr, 0); } jlongArray SWIG_JavaArrayOutUint (JNIEnv *jenv, unsigned int *result, jsize sz) { jlong *arr; int i; jlongArray jresult = (*jenv)->NewLongArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetLongArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseLongArrayElements(jenv, jresult, arr, 0); return jresult; } /* long[] support */ int SWIG_JavaArrayInLong (JNIEnv *jenv, jint **jarr, long **carr, jintArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetIntArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (long*) calloc(sz, sizeof(long)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseIntArrayElements(jenv, input, jarr, 0); } jintArray SWIG_JavaArrayOutLong (JNIEnv *jenv, long *result, jsize sz) { jint *arr; int i; jintArray jresult = (*jenv)->NewIntArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetIntArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseIntArrayElements(jenv, jresult, arr, 0); return jresult; } /* unsigned long[] support */ int SWIG_JavaArrayInUlong (JNIEnv *jenv, jlong **jarr, unsigned long **carr, jlongArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetLongArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (unsigned long*) calloc(sz, sizeof(unsigned long)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseLongArrayElements(jenv, input, jarr, 0); } jlongArray SWIG_JavaArrayOutUlong (JNIEnv *jenv, unsigned long *result, jsize sz) { jlong *arr; int i; jlongArray jresult = (*jenv)->NewLongArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetLongArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseLongArrayElements(jenv, jresult, arr, 0); return jresult; } /* jlong[] support */ int SWIG_JavaArrayInLonglong (JNIEnv *jenv, jlong **jarr, jlong **carr, jlongArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetLongArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (jlong*) calloc(sz, sizeof(jlong)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseLongArrayElements(jenv, input, jarr, 0); } jlongArray SWIG_JavaArrayOutLonglong (JNIEnv *jenv, jlong *result, jsize sz) { jlong *arr; int i; jlongArray jresult = (*jenv)->NewLongArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetLongArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseLongArrayElements(jenv, jresult, arr, 0); return jresult; } /* float[] support */ int SWIG_JavaArrayInFloat (JNIEnv *jenv, jfloat **jarr, float **carr, jfloatArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetFloatArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (float*) calloc(sz, sizeof(float)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseFloatArrayElements(jenv, input, jarr, 0); } jfloatArray SWIG_JavaArrayOutFloat (JNIEnv *jenv, float *result, jsize sz) { jfloat *arr; int i; jfloatArray jresult = (*jenv)->NewFloatArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetFloatArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseFloatArrayElements(jenv, jresult, arr, 0); return jresult; } /* double[] support */ int SWIG_JavaArrayInDouble (JNIEnv *jenv, jdouble **jarr, double **carr, jdoubleArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetDoubleArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (double*) calloc(sz, sizeof(double)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseDoubleArrayElements(jenv, input, jarr, 0); } jdoubleArray SWIG_JavaArrayOutDouble (JNIEnv *jenv, double *result, jsize sz) { jdouble *arr; int i; jdoubleArray jresult = (*jenv)->NewDoubleArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetDoubleArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseDoubleArrayElements(jenv, jresult, arr, 0); return jresult; } #endif #include "webp/types.h" int SWIG_JavaArrayInUint8 (JNIEnv *jenv, jbyte **jarr, uint8_t **carr, jbyteArray input); void SWIG_JavaArrayArgoutUint8 (JNIEnv *jenv, jbyte *jarr, uint8_t *carr, jbyteArray input); jbyteArray SWIG_JavaArrayOutUint8 (JNIEnv *jenv, uint8_t *result, jsize sz); /* uint8_t[] support */ int SWIG_JavaArrayInUint8 (JNIEnv *jenv, jbyte **jarr, uint8_t **carr, jbyteArray input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = (*jenv)->GetArrayLength(jenv, input); *jarr = (*jenv)->GetByteArrayElements(jenv, input, 0); if (!*jarr) return 0; *carr = (uint8_t*) calloc(sz, sizeof(uint8_t)); if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; iGetArrayLength(jenv, input); for (i=0; iReleaseByteArrayElements(jenv, input, jarr, 0); } jbyteArray SWIG_JavaArrayOutUint8 (JNIEnv *jenv, uint8_t *result, jsize sz) { jbyte *arr; int i; jbyteArray jresult = (*jenv)->NewByteArray(jenv, sz); if (!jresult) return NULL; arr = (*jenv)->GetByteArrayElements(jenv, jresult, 0); if (!arr) return NULL; for (i=0; iReleaseByteArrayElements(jenv, jresult, arr, 0); return jresult; } #include "webp/decode.h" #include "webp/encode.h" #define FillMeInAsSizeCannotBeDeterminedAutomatically \ (result ? (jint)ReturnedBufferSize(__FUNCTION__, arg3, arg4) : 0) static size_t ReturnedBufferSize( const char* function, int* width, int* height) { static const struct sizemap { const char* function; int size_multiplier; } size_map[] = { #ifdef SWIGJAVA { "Java_com_google_webp_libwebpJNI_WebPDecodeRGB", 3 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeRGBA", 4 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeARGB", 4 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeBGR", 3 }, { "Java_com_google_webp_libwebpJNI_WebPDecodeBGRA", 4 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGB", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGR", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGBA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGRA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGB", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGR", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGBA", 1 }, { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGRA", 1 }, #endif #ifdef SWIGPYTHON { "WebPDecodeRGB", 3 }, { "WebPDecodeRGBA", 4 }, { "WebPDecodeARGB", 4 }, { "WebPDecodeBGR", 3 }, { "WebPDecodeBGRA", 4 }, { "wrap_WebPEncodeRGB", 1 }, { "wrap_WebPEncodeBGR", 1 }, { "wrap_WebPEncodeRGBA", 1 }, { "wrap_WebPEncodeBGRA", 1 }, { "wrap_WebPEncodeLosslessRGB", 1 }, { "wrap_WebPEncodeLosslessBGR", 1 }, { "wrap_WebPEncodeLosslessRGBA", 1 }, { "wrap_WebPEncodeLosslessBGRA", 1 }, #endif { NULL, 0 } }; const struct sizemap* p; size_t size = 0; for (p = size_map; p->function; ++p) { if (!strcmp(function, p->function)) { size = *width * *height * p->size_multiplier; break; } } return size; } typedef size_t (*WebPEncodeFunction)(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); typedef size_t (*WebPEncodeLosslessFunction)(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); static uint8_t* EncodeLossy(const uint8_t* rgb, int width, int height, int stride, float quality_factor, WebPEncodeFunction encfn, int* output_size, int* unused) { uint8_t* output = NULL; const size_t image_size = encfn(rgb, width, height, stride, quality_factor, &output); // the values of following two will be interpreted by ReturnedBufferSize() // as 'width' and 'height' in the size calculation. *output_size = image_size; *unused = 1; return image_size ? output : NULL; } static uint8_t* EncodeLossless(const uint8_t* rgb, int width, int height, int stride, WebPEncodeLosslessFunction encfn, int* output_size, int* unused) { uint8_t* output = NULL; const size_t image_size = encfn(rgb, width, height, stride, &output); // the values of the following two will be interpreted by // ReturnedBufferSize() as 'width' and 'height' in the size calculation. *output_size = image_size; *unused = 1; return image_size ? output : NULL; } // Changes the return type of WebPEncode* to more closely match Decode*. // This also makes it easier to wrap the output buffer in a native type rather // than dealing with the return pointer. // The additional parameters are to allow reuse of ReturnedBufferSize(), // unused2 and output_size will be used in this case. #define LOSSY_WRAPPER(FUNC) \ static uint8_t* wrap_##FUNC( \ const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ int width, int height, int stride, float quality_factor) { \ return EncodeLossy(rgb, width, height, stride, quality_factor, \ FUNC, output_size, unused2); \ } \ LOSSY_WRAPPER(WebPEncodeRGB) LOSSY_WRAPPER(WebPEncodeBGR) LOSSY_WRAPPER(WebPEncodeRGBA) LOSSY_WRAPPER(WebPEncodeBGRA) #undef LOSSY_WRAPPER #define LOSSLESS_WRAPPER(FUNC) \ static uint8_t* wrap_##FUNC( \ const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ int width, int height, int stride) { \ return EncodeLossless(rgb, width, height, stride, \ FUNC, output_size, unused2); \ } \ LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) #undef LOSSLESS_WRAPPER /* Work around broken gcj jni.h */ #ifdef __GCJ_JNI_H__ # undef JNIEXPORT # define JNIEXPORT # undef JNICALL # define JNICALL #endif #ifdef __cplusplus extern "C" { #endif SWIGEXPORT jint JNICALL Java_com_google_webp_libwebpJNI_WebPGetDecoderVersion(JNIEnv *jenv, jclass jcls) { jint jresult = 0 ; int result; (void)jenv; (void)jcls; result = (int)WebPGetDecoderVersion(); jresult = (jint)result; return jresult; } SWIGEXPORT jint JNICALL Java_com_google_webp_libwebpJNI_WebPGetInfo(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jlong jarg2, jintArray jarg3, jintArray jarg4) { jint jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; int result; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (size_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } result = (int)WebPGetInfo((uint8_t const *)arg1,arg2,arg3,arg4); jresult = (jint)result; SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_WebPDecodeRGB(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jlong jarg2, jintArray jarg3, jintArray jarg4) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (size_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } result = (uint8_t *)WebPDecodeRGB((uint8_t const *)arg1,arg2,arg3,arg4); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_WebPDecodeRGBA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jlong jarg2, jintArray jarg3, jintArray jarg4) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (size_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } result = (uint8_t *)WebPDecodeRGBA((uint8_t const *)arg1,arg2,arg3,arg4); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_WebPDecodeARGB(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jlong jarg2, jintArray jarg3, jintArray jarg4) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (size_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } result = (uint8_t *)WebPDecodeARGB((uint8_t const *)arg1,arg2,arg3,arg4); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_WebPDecodeBGR(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jlong jarg2, jintArray jarg3, jintArray jarg4) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (size_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } result = (uint8_t *)WebPDecodeBGR((uint8_t const *)arg1,arg2,arg3,arg4); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_WebPDecodeBGRA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jlong jarg2, jintArray jarg3, jintArray jarg4) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; size_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (size_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } result = (uint8_t *)WebPDecodeBGRA((uint8_t const *)arg1,arg2,arg3,arg4); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jint JNICALL Java_com_google_webp_libwebpJNI_WebPGetEncoderVersion(JNIEnv *jenv, jclass jcls) { jint jresult = 0 ; int result; (void)jenv; (void)jcls; result = (int)WebPGetEncoderVersion(); jresult = (jint)result; return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGB(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7, jfloat jarg8) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; arg8 = (float)jarg8; result = (uint8_t *)wrap_WebPEncodeRGB((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGR(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7, jfloat jarg8) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; arg8 = (float)jarg8; result = (uint8_t *)wrap_WebPEncodeBGR((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGBA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7, jfloat jarg8) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; arg8 = (float)jarg8; result = (uint8_t *)wrap_WebPEncodeRGBA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGRA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7, jfloat jarg8) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; float arg8 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; arg8 = (float)jarg8; result = (uint8_t *)wrap_WebPEncodeBGRA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGB(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; result = (uint8_t *)wrap_WebPEncodeLosslessRGB((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGR(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; result = (uint8_t *)wrap_WebPEncodeLosslessBGR((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGBA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; result = (uint8_t *)wrap_WebPEncodeLosslessRGBA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGRA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jint jarg3, jintArray jarg4, jint jarg5, jint jarg6, jint jarg7) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; int *arg2 = (int *) 0 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; int arg5 ; int arg6 ; int arg7 ; jbyte *jarr1 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInUint8(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (int *)&jarg2; arg3 = (int *)&jarg3; { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (int)jarg7; result = (uint8_t *)wrap_WebPEncodeLosslessBGRA((uint8_t const *)arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = SWIG_JavaArrayOutUint8(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutUint8(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; } #ifdef __cplusplus } #endif libwebp-0.4.0/swig/setup.py0000644000014400001440000000226012255002107012524 0ustar #!/usr/bin/python """distutils script for libwebp python module.""" from distutils.core import setup from distutils.extension import Extension import os import shutil import tempfile tmpdir = tempfile.mkdtemp() package = "com.google.webp" package_path = os.path.join(tmpdir, *package.split(".")) os.makedirs(package_path) # Create __init_.py files along the package path. initpy_path = tmpdir for d in package.split("."): initpy_path = os.path.join(initpy_path, d) open(os.path.join(initpy_path, "__init__.py"), "w").close() shutil.copy2("libwebp.py", package_path) setup(name="libwebp", version="0.0", description="libwebp python wrapper", long_description="Provides access to 'simple' libwebp decode interface", license="BSD", url="http://developers.google.com/speed/webp", ext_package=package, ext_modules=[Extension("_libwebp", ["libwebp_python_wrap.c"], libraries=["webp"], ), ], package_dir={"": tmpdir}, packages=["com", "com.google", "com.google.webp"], py_modules=[package + ".libwebp"], ) shutil.rmtree(tmpdir) libwebp-0.4.0/swig/libwebp.jar0000644000014400001440000000414612255002107013141 0ustar PKíŒKC META-INF/þÊPKPKíŒKCMETA-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ˜éÄ›˜*h—æ)øf&åW—¤æ+xæ%ëiòrñrPK{ª×ïGGPK íŒKCcom/PK íŒKC com/google/PK íŒKCcom/google/webp/PKíŒKCcom/google/webp/libwebp.class…”kSQÇÿ+7Y¼…&HfæBÔÔò’^34Q¼P9@›á ëpÑ™fz×ÇéE—9MÓèC5=ϲ£ytùÁžóÿ眳‡ýó÷çoãØ—Ñ˜Œ¨R³Ïå ¹ò¼ËÐpR‚uA{K]Í«¹‚¯eÔâf:“§϶šYªåE5K‰bR-–rZA×h”&£7Vx§Q•¡Td%KŸËÅ]Uk#¡èygŠîÜ—z×Âzþ??ݸ ûðÅÌ– —gÖvZLïsgµGÍMÕcTœ>ËúÄ”^£ýª¾ÚZ-ïZWµR)¯–JÕÉ_”Ó«™…õª>ó‘Âæ½ÕY¸„uÊzacnq%.a½nqQ“õ8«Ãê£v˜ÍôY¯rP­Ö8—ͧPNh•bV]Îñ™Sò¹Ì©š99LŸ¤ôá®o bHÁ0 îᾂ c„bŒ2Æ82Ž &“Œ)ÆCÑ’—Ï_p}º@ï2ë/y×bYûŽ6ñ5'FÁoÉgÿPK~¥yIX PKíŒKC com/google/webp/libwebpJNI.classu’ÍNÂ@…ïð«åDDź°‰kcRTH Aƒ]˜¶Ž¤¤´¤y.W&.|Êxg: aóÍÜs´ß?Ÿ_p'Dá( ÇIhH\ZŽ5»"mž Ä®ÝJ ׳ÚŸO ê=ꆕò5î;tvCMtxCêù–ëð6•@J¨ªóêšZ««©šÊ¤ “‚®A§…Ö?QÃ[6¤*¡‚Âýÿú[AÈ€we9Ù­ž¬¸ðôé3…¿–ÅtÃqµù«.žQZoUÖ«A|u¥Ús}ߦ¾ ¿Œãi›Ì<µ¶ù%e³L!=¸sϤm‹}«œm jL»}õ|¬¿éiˆAÃMw"\wdS™ÉòÒF ÏŒ²­;#ùÎSs ˆàÂV{÷ÞêH‚ŒŸ}yÇ$î ^L‘ lÁ6+ AŠ3 ά`N0/X,оìp–w÷÷¡ÂY¬ 0âuÜ#pø PK`­éQpñPKíŒKC META-INF/þÊPKíŒKC{ª×ïGG=META-INF/MANIFEST.MFPK íŒKCÆcom/PK íŒKC ècom/google/PK íŒKCcom/google/webp/PKíŒKC~¥yIX ?com/google/webp/libwebp.classPKíŒKC`­éQpñ Ócom/google/webp/libwebpJNI.classPK¿‘libwebp-0.4.0/iosbuild.sh0000755000014400001440000000613412255002107012216 0ustar #!/bin/bash # # This script generates 'WebP.framework'. An iOS app can decode WebP images # by including 'WebP.framework'. # # Run ./iosbuild.sh to generate 'WebP.framework' under the current directory # (previous build will be erased if it exists). # # This script is inspired by the build script written by Carson McDonald. # (http://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/). set -e # Extract the latest SDK version from the final field of the form: iphoneosX.Y declare -r SDK=$(xcodebuild -showsdks \ | grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}' ) # Extract Xcode version. declare -r XCODE=$(xcodebuild -version | grep Xcode | cut -d " " -f2) declare -r OLDPATH=${PATH} # Add iPhoneOS-V6 to the list of platforms below if you need armv6 support. # Note that iPhoneOS-V6 support is not available with the iOS6 SDK. declare -r PLATFORMS="iPhoneSimulator iPhoneOS-V7 iPhoneOS-V7s" declare -r SRCDIR=$(dirname $0) declare -r TOPDIR=$(pwd) declare -r BUILDDIR="${TOPDIR}/iosbuild" declare -r TARGETDIR="${TOPDIR}/WebP.framework" declare -r DEVELOPER=$(xcode-select --print-path) declare -r PLATFORMSROOT="${DEVELOPER}/Platforms" declare -r LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo) LIBLIST='' if [[ -z "${SDK}" ]]; then echo "iOS SDK not available" exit 1 elif [[ ${SDK} < 4.0 ]]; then echo "You need iOS SDK version 4.0 or above" exit 1 else echo "iOS SDK Version ${SDK}" fi rm -rf ${BUILDDIR} rm -rf ${TARGETDIR} mkdir -p ${BUILDDIR} mkdir -p ${TARGETDIR}/Headers/ [[ -e ${SRCDIR}/configure ]] || (cd ${SRCDIR} && sh autogen.sh) for PLATFORM in ${PLATFORMS}; do if [[ "${PLATFORM}" == "iPhoneOS-V7s" ]]; then PLATFORM="iPhoneOS" ARCH="armv7s" elif [[ "${PLATFORM}" == "iPhoneOS-V7" ]]; then PLATFORM="iPhoneOS" ARCH="armv7" elif [[ "${PLATFORM}" == "iPhoneOS-V6" ]]; then PLATFORM="iPhoneOS" ARCH="armv6" else ARCH="i386" fi ROOTDIR="${BUILDDIR}/${PLATFORM}-${SDK}-${ARCH}" mkdir -p "${ROOTDIR}" SDKROOT="${PLATFORMSROOT}/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/" CFLAGS="-arch ${ARCH} -pipe -isysroot ${SDKROOT}" LDFLAGS="-arch ${ARCH} -pipe -isysroot ${SDKROOT}" if [[ -z "${XCODE}" ]]; then echo "XCODE not available" exit 1 elif [[ ${SDK} < 5.0.0 ]]; then DEVROOT="${PLATFORMSROOT}/${PLATFORM}.platform/Developer/" else DEVROOT="${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain" CFLAGS+=" -miphoneos-version-min=5.0" LDFLAGS+=" -miphoneos-version-min=5.0" fi export CFLAGS export LDFLAGS export CXXFLAGS=${CFLAGS} export PATH="${DEVROOT}/usr/bin:${OLDPATH}" ${SRCDIR}/configure --host=${ARCH}-apple-darwin --prefix=${ROOTDIR} \ --build=$(${SRCDIR}/config.guess) \ --disable-shared --enable-static \ --enable-libwebpdecoder --enable-swap-16bit-csp # run make only in the src/ directory to create libwebpdecoder.a cd src/ make V=0 make install LIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a" make clean cd .. export PATH=${OLDPATH} done cp -a ${SRCDIR}/src/webp/* ${TARGETDIR}/Headers/ ${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP libwebp-0.4.0/COPYING0000644000014400001440000000273012255002107011076 0ustar Copyright (c) 2010, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * 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. 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. libwebp-0.4.0/autogen.sh0000755000014400001440000000004212255002107012036 0ustar #! /bin/sh -e exec autoreconf -fi libwebp-0.4.0/AUTHORS0000644000014400001440000000143512255002107011114 0ustar Contributors: - Charles Munger (clm at google dot com) - Christian Duvivier (cduvivier at google dot com) - James Zern (jzern at google dot com) - Jan Engelhardt (jengelh at medozas dot de) - Johann (johann dot koenig at duck dot com) - Jyrki Alakuijala (jyrki at google dot com) - Lou Quillio (louquillio at google dot com) - Mans Rullgard (mans at mansr dot com) - Martin Olsson (mnemo at minimum dot se) - MikoÅ‚aj Zalewski (mikolajz at google dot com) - Noel Chromium (noel at chromium dot org) - Pascal Massimino (pascal dot massimino at gmail dot com) - Pierre Joye (pierre dot php at gmail dot com) - Scott LaVarnway (slavarnway at google dot com) - Somnath Banerjee (somnath dot banerjee at gmail dot com) - Urvang Joshi (urvang at google dot com) - Vikas Arora (vikasa at google dot com) libwebp-0.4.0/m4/0000755000014400001440000000000012255206711010370 5ustar libwebp-0.4.0/m4/ltoptions.m40000644000014400001440000003007312255206711012670 0ustar # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) libwebp-0.4.0/m4/ltversion.m40000644000014400001440000000126212255206711012660 0ustar # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file 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. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libwebp-0.4.0/m4/libtool.m40000644000014400001440000106043412255206711012306 0ustar # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS libwebp-0.4.0/m4/ltsugar.m40000644000014400001440000001042412255206711012314 0ustar # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) libwebp-0.4.0/m4/ax_pthread.m40000644000014400001440000003036612255002107012752 0ustar # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # 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 . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 18 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) AC_MSG_RESULT($ax_pthread_ok) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($ax_pthread_ok) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], ax_cv_PTHREAD_PRIO_INHERIT, [ AC_LINK_IFELSE([ AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD libwebp-0.4.0/m4/lt~obsolete.m40000644000014400001440000001375612255206711013220 0ustar # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file 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. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) libwebp-0.4.0/src/0000755000014400001440000000000012255206714010642 5ustar libwebp-0.4.0/src/libwebpdecoder.pc.in0000644000014400001440000000045512255002107014537 0ustar prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libwebpdecoder Description: Library for the WebP graphics format (decode only) Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lwebpdecoder Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ libwebp-0.4.0/src/mux/0000755000014400001440000000000012255206714011453 5ustar libwebp-0.4.0/src/mux/muxinternal.c0000644000014400001440000004310112255002107014152 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Internal objects and utils for mux. // // Authors: Urvang (urvang@google.com) // Vikas (vikasa@google.com) #include #include "./muxi.h" #include "../utils/utils.h" #define UNDEFINED_CHUNK_SIZE (-1) const ChunkInfo kChunks[] = { { MKFOURCC('V', 'P', '8', 'X'), WEBP_CHUNK_VP8X, VP8X_CHUNK_SIZE }, { MKFOURCC('I', 'C', 'C', 'P'), WEBP_CHUNK_ICCP, UNDEFINED_CHUNK_SIZE }, { MKFOURCC('A', 'N', 'I', 'M'), WEBP_CHUNK_ANIM, ANIM_CHUNK_SIZE }, { MKFOURCC('A', 'N', 'M', 'F'), WEBP_CHUNK_ANMF, ANMF_CHUNK_SIZE }, { MKFOURCC('F', 'R', 'G', 'M'), WEBP_CHUNK_FRGM, FRGM_CHUNK_SIZE }, { MKFOURCC('A', 'L', 'P', 'H'), WEBP_CHUNK_ALPHA, UNDEFINED_CHUNK_SIZE }, { MKFOURCC('V', 'P', '8', ' '), WEBP_CHUNK_IMAGE, UNDEFINED_CHUNK_SIZE }, { MKFOURCC('V', 'P', '8', 'L'), WEBP_CHUNK_IMAGE, UNDEFINED_CHUNK_SIZE }, { MKFOURCC('E', 'X', 'I', 'F'), WEBP_CHUNK_EXIF, UNDEFINED_CHUNK_SIZE }, { MKFOURCC('X', 'M', 'P', ' '), WEBP_CHUNK_XMP, UNDEFINED_CHUNK_SIZE }, { NIL_TAG, WEBP_CHUNK_UNKNOWN, UNDEFINED_CHUNK_SIZE }, { NIL_TAG, WEBP_CHUNK_NIL, UNDEFINED_CHUNK_SIZE } }; //------------------------------------------------------------------------------ int WebPGetMuxVersion(void) { return (MUX_MAJ_VERSION << 16) | (MUX_MIN_VERSION << 8) | MUX_REV_VERSION; } //------------------------------------------------------------------------------ // Life of a chunk object. void ChunkInit(WebPChunk* const chunk) { assert(chunk); memset(chunk, 0, sizeof(*chunk)); chunk->tag_ = NIL_TAG; } WebPChunk* ChunkRelease(WebPChunk* const chunk) { WebPChunk* next; if (chunk == NULL) return NULL; if (chunk->owner_) { WebPDataClear(&chunk->data_); } next = chunk->next_; ChunkInit(chunk); return next; } //------------------------------------------------------------------------------ // Chunk misc methods. CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag) { int i; for (i = 0; kChunks[i].tag != NIL_TAG; ++i) { if (tag == kChunks[i].tag) return (CHUNK_INDEX)i; } return IDX_UNKNOWN; } WebPChunkId ChunkGetIdFromTag(uint32_t tag) { int i; for (i = 0; kChunks[i].tag != NIL_TAG; ++i) { if (tag == kChunks[i].tag) return kChunks[i].id; } return WEBP_CHUNK_UNKNOWN; } uint32_t ChunkGetTagFromFourCC(const char fourcc[4]) { return MKFOURCC(fourcc[0], fourcc[1], fourcc[2], fourcc[3]); } CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]) { const uint32_t tag = ChunkGetTagFromFourCC(fourcc); return ChunkGetIndexFromTag(tag); } //------------------------------------------------------------------------------ // Chunk search methods. // Returns next chunk in the chunk list with the given tag. static WebPChunk* ChunkSearchNextInList(WebPChunk* chunk, uint32_t tag) { while (chunk != NULL && chunk->tag_ != tag) { chunk = chunk->next_; } return chunk; } WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag) { uint32_t iter = nth; first = ChunkSearchNextInList(first, tag); if (first == NULL) return NULL; while (--iter != 0) { WebPChunk* next_chunk = ChunkSearchNextInList(first->next_, tag); if (next_chunk == NULL) break; first = next_chunk; } return ((nth > 0) && (iter > 0)) ? NULL : first; } // Outputs a pointer to 'prev_chunk->next_', // where 'prev_chunk' is the pointer to the chunk at position (nth - 1). // Returns true if nth chunk was found. static int ChunkSearchListToSet(WebPChunk** chunk_list, uint32_t nth, WebPChunk*** const location) { uint32_t count = 0; assert(chunk_list != NULL); *location = chunk_list; while (*chunk_list != NULL) { WebPChunk* const cur_chunk = *chunk_list; ++count; if (count == nth) return 1; // Found. chunk_list = &cur_chunk->next_; *location = chunk_list; } // *chunk_list is ok to be NULL if adding at last location. return (nth == 0 || (count == nth - 1)) ? 1 : 0; } //------------------------------------------------------------------------------ // Chunk writer methods. WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data, int copy_data, uint32_t tag) { // For internally allocated chunks, always copy data & make it owner of data. if (tag == kChunks[IDX_VP8X].tag || tag == kChunks[IDX_ANIM].tag) { copy_data = 1; } ChunkRelease(chunk); if (data != NULL) { if (copy_data) { // Copy data. if (!WebPDataCopy(data, &chunk->data_)) return WEBP_MUX_MEMORY_ERROR; chunk->owner_ = 1; // Chunk is owner of data. } else { // Don't copy data. chunk->data_ = *data; } } chunk->tag_ = tag; return WEBP_MUX_OK; } WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list, uint32_t nth) { WebPChunk* new_chunk; if (!ChunkSearchListToSet(chunk_list, nth, &chunk_list)) { return WEBP_MUX_NOT_FOUND; } new_chunk = (WebPChunk*)malloc(sizeof(*new_chunk)); if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR; *new_chunk = *chunk; chunk->owner_ = 0; new_chunk->next_ = *chunk_list; *chunk_list = new_chunk; return WEBP_MUX_OK; } //------------------------------------------------------------------------------ // Chunk deletion method(s). WebPChunk* ChunkDelete(WebPChunk* const chunk) { WebPChunk* const next = ChunkRelease(chunk); free(chunk); return next; } void ChunkListDelete(WebPChunk** const chunk_list) { while (*chunk_list != NULL) { *chunk_list = ChunkDelete(*chunk_list); } } //------------------------------------------------------------------------------ // Chunk serialization methods. static uint8_t* ChunkEmit(const WebPChunk* const chunk, uint8_t* dst) { const size_t chunk_size = chunk->data_.size; assert(chunk); assert(chunk->tag_ != NIL_TAG); PutLE32(dst + 0, chunk->tag_); PutLE32(dst + TAG_SIZE, (uint32_t)chunk_size); assert(chunk_size == (uint32_t)chunk_size); memcpy(dst + CHUNK_HEADER_SIZE, chunk->data_.bytes, chunk_size); if (chunk_size & 1) dst[CHUNK_HEADER_SIZE + chunk_size] = 0; // Add padding. return dst + ChunkDiskSize(chunk); } uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) { while (chunk_list != NULL) { dst = ChunkEmit(chunk_list, dst); chunk_list = chunk_list->next_; } return dst; } size_t ChunkListDiskSize(const WebPChunk* chunk_list) { size_t size = 0; while (chunk_list != NULL) { size += ChunkDiskSize(chunk_list); chunk_list = chunk_list->next_; } return size; } //------------------------------------------------------------------------------ // Life of a MuxImage object. void MuxImageInit(WebPMuxImage* const wpi) { assert(wpi); memset(wpi, 0, sizeof(*wpi)); } WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) { WebPMuxImage* next; if (wpi == NULL) return NULL; ChunkDelete(wpi->header_); ChunkDelete(wpi->alpha_); ChunkDelete(wpi->img_); ChunkListDelete(&wpi->unknown_); next = wpi->next_; MuxImageInit(wpi); return next; } //------------------------------------------------------------------------------ // MuxImage search methods. // Get a reference to appropriate chunk list within an image given chunk tag. static WebPChunk** GetChunkListFromId(const WebPMuxImage* const wpi, WebPChunkId id) { assert(wpi != NULL); switch (id) { case WEBP_CHUNK_ANMF: case WEBP_CHUNK_FRGM: return (WebPChunk**)&wpi->header_; case WEBP_CHUNK_ALPHA: return (WebPChunk**)&wpi->alpha_; case WEBP_CHUNK_IMAGE: return (WebPChunk**)&wpi->img_; default: return NULL; } } int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id) { int count = 0; const WebPMuxImage* current; for (current = wpi_list; current != NULL; current = current->next_) { if (id == WEBP_CHUNK_NIL) { ++count; // Special case: count all images. } else { const WebPChunk* const wpi_chunk = *GetChunkListFromId(current, id); if (wpi_chunk != NULL) { const WebPChunkId wpi_chunk_id = ChunkGetIdFromTag(wpi_chunk->tag_); if (wpi_chunk_id == id) ++count; // Count images with a matching 'id'. } } } return count; } // Outputs a pointer to 'prev_wpi->next_', // where 'prev_wpi' is the pointer to the image at position (nth - 1). // Returns true if nth image was found. static int SearchImageToGetOrDelete(WebPMuxImage** wpi_list, uint32_t nth, WebPMuxImage*** const location) { uint32_t count = 0; assert(wpi_list); *location = wpi_list; if (nth == 0) { nth = MuxImageCount(*wpi_list, WEBP_CHUNK_NIL); if (nth == 0) return 0; // Not found. } while (*wpi_list != NULL) { WebPMuxImage* const cur_wpi = *wpi_list; ++count; if (count == nth) return 1; // Found. wpi_list = &cur_wpi->next_; *location = wpi_list; } return 0; // Not found. } //------------------------------------------------------------------------------ // MuxImage writer methods. WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list) { WebPMuxImage* new_wpi; while (*wpi_list != NULL) { WebPMuxImage* const cur_wpi = *wpi_list; if (cur_wpi->next_ == NULL) break; wpi_list = &cur_wpi->next_; } new_wpi = (WebPMuxImage*)malloc(sizeof(*new_wpi)); if (new_wpi == NULL) return WEBP_MUX_MEMORY_ERROR; *new_wpi = *wpi; new_wpi->next_ = NULL; if (*wpi_list != NULL) { (*wpi_list)->next_ = new_wpi; } else { *wpi_list = new_wpi; } return WEBP_MUX_OK; } //------------------------------------------------------------------------------ // MuxImage deletion methods. WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi) { // Delete the components of wpi. If wpi is NULL this is a noop. WebPMuxImage* const next = MuxImageRelease(wpi); free(wpi); return next; } WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth) { assert(wpi_list); if (!SearchImageToGetOrDelete(wpi_list, nth, &wpi_list)) { return WEBP_MUX_NOT_FOUND; } *wpi_list = MuxImageDelete(*wpi_list); return WEBP_MUX_OK; } //------------------------------------------------------------------------------ // MuxImage reader methods. WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth, WebPMuxImage** wpi) { assert(wpi_list); assert(wpi); if (!SearchImageToGetOrDelete((WebPMuxImage**)wpi_list, nth, (WebPMuxImage***)&wpi_list)) { return WEBP_MUX_NOT_FOUND; } *wpi = (WebPMuxImage*)*wpi_list; return WEBP_MUX_OK; } //------------------------------------------------------------------------------ // MuxImage serialization methods. // Size of an image. size_t MuxImageDiskSize(const WebPMuxImage* const wpi) { size_t size = 0; if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_); if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_); if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_); if (wpi->unknown_ != NULL) size += ChunkListDiskSize(wpi->unknown_); return size; } // Special case as ANMF/FRGM chunk encapsulates other image chunks. static uint8_t* ChunkEmitSpecial(const WebPChunk* const header, size_t total_size, uint8_t* dst) { const size_t header_size = header->data_.size; const size_t offset_to_next = total_size - CHUNK_HEADER_SIZE; assert(header->tag_ == kChunks[IDX_ANMF].tag || header->tag_ == kChunks[IDX_FRGM].tag); PutLE32(dst + 0, header->tag_); PutLE32(dst + TAG_SIZE, (uint32_t)offset_to_next); assert(header_size == (uint32_t)header_size); memcpy(dst + CHUNK_HEADER_SIZE, header->data_.bytes, header_size); if (header_size & 1) { dst[CHUNK_HEADER_SIZE + header_size] = 0; // Add padding. } return dst + ChunkDiskSize(header); } uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst) { // Ordering of chunks to be emitted is strictly as follows: // 1. ANMF/FRGM chunk (if present). // 2. ALPH chunk (if present). // 3. VP8/VP8L chunk. assert(wpi); if (wpi->header_ != NULL) { dst = ChunkEmitSpecial(wpi->header_, MuxImageDiskSize(wpi), dst); } if (wpi->alpha_ != NULL) dst = ChunkEmit(wpi->alpha_, dst); if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst); if (wpi->unknown_ != NULL) dst = ChunkListEmit(wpi->unknown_, dst); return dst; } //------------------------------------------------------------------------------ // Helper methods for mux. int MuxHasAlpha(const WebPMuxImage* images) { while (images != NULL) { if (images->has_alpha_) return 1; images = images->next_; } return 0; } uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size) { PutLE32(data + 0, MKFOURCC('R', 'I', 'F', 'F')); PutLE32(data + TAG_SIZE, (uint32_t)size - CHUNK_HEADER_SIZE); assert(size == (uint32_t)size); PutLE32(data + TAG_SIZE + CHUNK_SIZE_BYTES, MKFOURCC('W', 'E', 'B', 'P')); return data + RIFF_HEADER_SIZE; } WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id) { assert(mux != NULL); switch (id) { case WEBP_CHUNK_VP8X: return (WebPChunk**)&mux->vp8x_; case WEBP_CHUNK_ICCP: return (WebPChunk**)&mux->iccp_; case WEBP_CHUNK_ANIM: return (WebPChunk**)&mux->anim_; case WEBP_CHUNK_EXIF: return (WebPChunk**)&mux->exif_; case WEBP_CHUNK_XMP: return (WebPChunk**)&mux->xmp_; default: return (WebPChunk**)&mux->unknown_; } } static int IsNotCompatible(int feature, int num_items) { return (feature != 0) != (num_items > 0); } #define NO_FLAG 0 // Test basic constraints: // retrieval, maximum number of chunks by index (use -1 to skip) // and feature incompatibility (use NO_FLAG to skip). // On success returns WEBP_MUX_OK and stores the chunk count in *num. static WebPMuxError ValidateChunk(const WebPMux* const mux, CHUNK_INDEX idx, WebPFeatureFlags feature, uint32_t vp8x_flags, int max, int* num) { const WebPMuxError err = WebPMuxNumChunks(mux, kChunks[idx].id, num); if (err != WEBP_MUX_OK) return err; if (max > -1 && *num > max) return WEBP_MUX_INVALID_ARGUMENT; if (feature != NO_FLAG && IsNotCompatible(vp8x_flags & feature, *num)) { return WEBP_MUX_INVALID_ARGUMENT; } return WEBP_MUX_OK; } WebPMuxError MuxValidate(const WebPMux* const mux) { int num_iccp; int num_exif; int num_xmp; int num_anim; int num_frames; int num_fragments; int num_vp8x; int num_images; int num_alpha; uint32_t flags; WebPMuxError err; // Verify mux is not NULL. if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT; // Verify mux has at least one image. if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT; err = WebPMuxGetFeatures(mux, &flags); if (err != WEBP_MUX_OK) return err; // At most one color profile chunk. err = ValidateChunk(mux, IDX_ICCP, ICCP_FLAG, flags, 1, &num_iccp); if (err != WEBP_MUX_OK) return err; // At most one EXIF metadata. err = ValidateChunk(mux, IDX_EXIF, EXIF_FLAG, flags, 1, &num_exif); if (err != WEBP_MUX_OK) return err; // At most one XMP metadata. err = ValidateChunk(mux, IDX_XMP, XMP_FLAG, flags, 1, &num_xmp); if (err != WEBP_MUX_OK) return err; // Animation: ANIMATION_FLAG, ANIM chunk and ANMF chunk(s) are consistent. // At most one ANIM chunk. err = ValidateChunk(mux, IDX_ANIM, NO_FLAG, flags, 1, &num_anim); if (err != WEBP_MUX_OK) return err; err = ValidateChunk(mux, IDX_ANMF, NO_FLAG, flags, -1, &num_frames); if (err != WEBP_MUX_OK) return err; { const int has_animation = !!(flags & ANIMATION_FLAG); if (has_animation && (num_anim == 0 || num_frames == 0)) { return WEBP_MUX_INVALID_ARGUMENT; } if (!has_animation && (num_anim == 1 || num_frames > 0)) { return WEBP_MUX_INVALID_ARGUMENT; } } // Fragmentation: FRAGMENTS_FLAG and FRGM chunk(s) are consistent. err = ValidateChunk(mux, IDX_FRGM, FRAGMENTS_FLAG, flags, -1, &num_fragments); if (err != WEBP_MUX_OK) return err; // Verify either VP8X chunk is present OR there is only one elem in // mux->images_. err = ValidateChunk(mux, IDX_VP8X, NO_FLAG, flags, 1, &num_vp8x); if (err != WEBP_MUX_OK) return err; err = ValidateChunk(mux, IDX_VP8, NO_FLAG, flags, -1, &num_images); if (err != WEBP_MUX_OK) return err; if (num_vp8x == 0 && num_images != 1) return WEBP_MUX_INVALID_ARGUMENT; // ALPHA_FLAG & alpha chunk(s) are consistent. if (MuxHasAlpha(mux->images_)) { if (num_vp8x > 0) { // VP8X chunk is present, so it should contain ALPHA_FLAG. if (!(flags & ALPHA_FLAG)) return WEBP_MUX_INVALID_ARGUMENT; } else { // VP8X chunk is not present, so ALPH chunks should NOT be present either. err = WebPMuxNumChunks(mux, WEBP_CHUNK_ALPHA, &num_alpha); if (err != WEBP_MUX_OK) return err; if (num_alpha > 0) return WEBP_MUX_INVALID_ARGUMENT; } } else { // Mux doesn't need alpha. So, ALPHA_FLAG should NOT be present. if (flags & ALPHA_FLAG) return WEBP_MUX_INVALID_ARGUMENT; } // num_fragments & num_images are consistent. if (num_fragments > 0 && num_images != num_fragments) { return WEBP_MUX_INVALID_ARGUMENT; } return WEBP_MUX_OK; } #undef NO_FLAG //------------------------------------------------------------------------------ libwebp-0.4.0/src/mux/Makefile.in0000644000014400001440000005152012255206714013523 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ subdir = src/mux DIST_COMMON = $(libwebpmuxinclude_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/libwebpmux.pc.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libwebpmux.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(libwebpmuxincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libwebpmux_la_DEPENDENCIES = ../libwebp.la am_libwebpmux_la_OBJECTS = muxedit.lo muxinternal.lo muxread.lo libwebpmux_la_OBJECTS = $(am_libwebpmux_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libwebpmux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libwebpmux_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebpmux_la_SOURCES) DIST_SOURCES = $(libwebpmux_la_SOURCES) DATA = $(pkgconfig_DATA) HEADERS = $(libwebpmuxinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src lib_LTLIBRARIES = libwebpmux.la libwebpmux_la_SOURCES = muxedit.c muxi.h muxinternal.c muxread.c libwebpmuxinclude_HEADERS = ../webp/mux.h ../webp/mux_types.h \ ../webp/types.h libwebpmux_la_LIBADD = ../libwebp.la libwebpmux_la_LDFLAGS = -no-undefined -version-info 1:0:0 libwebpmuxincludedir = $(includedir)/webp pkgconfig_DATA = libwebpmux.pc all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/mux/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/mux/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libwebpmux.pc: $(top_builddir)/config.status $(srcdir)/libwebpmux.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebpmux.la: $(libwebpmux_la_OBJECTS) $(libwebpmux_la_DEPENDENCIES) $(EXTRA_libwebpmux_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebpmux_la_LINK) -rpath $(libdir) $(libwebpmux_la_OBJECTS) $(libwebpmux_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muxedit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muxinternal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muxread.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-libwebpmuxincludeHEADERS: $(libwebpmuxinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(libwebpmuxincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libwebpmuxincludedir)" @list='$(libwebpmuxinclude_HEADERS)'; test -n "$(libwebpmuxincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpmuxincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpmuxincludedir)" || exit $$?; \ done uninstall-libwebpmuxincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libwebpmuxinclude_HEADERS)'; test -n "$(libwebpmuxincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libwebpmuxincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libwebpmuxincludedir)"; 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-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-libwebpmuxincludeHEADERS \ install-pkgconfigDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES 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 -rf ./$(DEPDIR) -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-libLTLIBRARIES \ uninstall-libwebpmuxincludeHEADERS uninstall-pkgconfigDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES install-libwebpmuxincludeHEADERS \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ 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 uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-libwebpmuxincludeHEADERS uninstall-pkgconfigDATA # 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: libwebp-0.4.0/src/mux/muxread.c0000644000014400001440000004430712255002107013262 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Read APIs for mux. // // Authors: Urvang (urvang@google.com) // Vikas (vikasa@google.com) #include #include "./muxi.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ // Helper method(s). // Handy MACRO. #define SWITCH_ID_LIST(INDEX, LIST) \ if (idx == (INDEX)) { \ const WebPChunk* const chunk = ChunkSearchList((LIST), nth, \ kChunks[(INDEX)].tag); \ if (chunk) { \ *data = chunk->data_; \ return WEBP_MUX_OK; \ } else { \ return WEBP_MUX_NOT_FOUND; \ } \ } static WebPMuxError MuxGet(const WebPMux* const mux, CHUNK_INDEX idx, uint32_t nth, WebPData* const data) { assert(mux != NULL); assert(!IsWPI(kChunks[idx].id)); WebPDataInit(data); SWITCH_ID_LIST(IDX_VP8X, mux->vp8x_); SWITCH_ID_LIST(IDX_ICCP, mux->iccp_); SWITCH_ID_LIST(IDX_ANIM, mux->anim_); SWITCH_ID_LIST(IDX_EXIF, mux->exif_); SWITCH_ID_LIST(IDX_XMP, mux->xmp_); SWITCH_ID_LIST(IDX_UNKNOWN, mux->unknown_); return WEBP_MUX_NOT_FOUND; } #undef SWITCH_ID_LIST // Fill the chunk with the given data (includes chunk header bytes), after some // verifications. static WebPMuxError ChunkVerifyAndAssign(WebPChunk* chunk, const uint8_t* data, size_t data_size, size_t riff_size, int copy_data) { uint32_t chunk_size; WebPData chunk_data; // Sanity checks. if (data_size < TAG_SIZE) return WEBP_MUX_NOT_ENOUGH_DATA; chunk_size = GetLE32(data + TAG_SIZE); { const size_t chunk_disk_size = SizeWithPadding(chunk_size); if (chunk_disk_size > riff_size) return WEBP_MUX_BAD_DATA; if (chunk_disk_size > data_size) return WEBP_MUX_NOT_ENOUGH_DATA; } // Data assignment. chunk_data.bytes = data + CHUNK_HEADER_SIZE; chunk_data.size = chunk_size; return ChunkAssignData(chunk, &chunk_data, copy_data, GetLE32(data + 0)); } int MuxImageFinalize(WebPMuxImage* const wpi) { const WebPChunk* const img = wpi->img_; const WebPData* const image = &img->data_; const int is_lossless = (img->tag_ == kChunks[IDX_VP8L].tag); int w, h; int vp8l_has_alpha = 0; const int ok = is_lossless ? VP8LGetInfo(image->bytes, image->size, &w, &h, &vp8l_has_alpha) : VP8GetInfo(image->bytes, image->size, image->size, &w, &h); assert(img != NULL); if (ok) { // Ignore ALPH chunk accompanying VP8L. if (is_lossless && (wpi->alpha_ != NULL)) { ChunkDelete(wpi->alpha_); wpi->alpha_ = NULL; } wpi->width_ = w; wpi->height_ = h; wpi->has_alpha_ = vp8l_has_alpha || (wpi->alpha_ != NULL); } return ok; } static int MuxImageParse(const WebPChunk* const chunk, int copy_data, WebPMuxImage* const wpi) { const uint8_t* bytes = chunk->data_.bytes; size_t size = chunk->data_.size; const uint8_t* const last = bytes + size; WebPChunk subchunk; size_t subchunk_size; ChunkInit(&subchunk); assert(chunk->tag_ == kChunks[IDX_ANMF].tag || chunk->tag_ == kChunks[IDX_FRGM].tag); assert(!wpi->is_partial_); // ANMF/FRGM. { const size_t hdr_size = (chunk->tag_ == kChunks[IDX_ANMF].tag) ? ANMF_CHUNK_SIZE : FRGM_CHUNK_SIZE; const WebPData temp = { bytes, hdr_size }; // Each of ANMF and FRGM chunk contain a header at the beginning. So, its // size should at least be 'hdr_size'. if (size < hdr_size) goto Fail; ChunkAssignData(&subchunk, &temp, copy_data, chunk->tag_); } ChunkSetNth(&subchunk, &wpi->header_, 1); wpi->is_partial_ = 1; // Waiting for ALPH and/or VP8/VP8L chunks. // Rest of the chunks. subchunk_size = ChunkDiskSize(&subchunk) - CHUNK_HEADER_SIZE; bytes += subchunk_size; size -= subchunk_size; while (bytes != last) { ChunkInit(&subchunk); if (ChunkVerifyAndAssign(&subchunk, bytes, size, size, copy_data) != WEBP_MUX_OK) { goto Fail; } switch (ChunkGetIdFromTag(subchunk.tag_)) { case WEBP_CHUNK_ALPHA: if (wpi->alpha_ != NULL) goto Fail; // Consecutive ALPH chunks. if (ChunkSetNth(&subchunk, &wpi->alpha_, 1) != WEBP_MUX_OK) goto Fail; wpi->is_partial_ = 1; // Waiting for a VP8 chunk. break; case WEBP_CHUNK_IMAGE: if (ChunkSetNth(&subchunk, &wpi->img_, 1) != WEBP_MUX_OK) goto Fail; if (!MuxImageFinalize(wpi)) goto Fail; wpi->is_partial_ = 0; // wpi is completely filled. break; case WEBP_CHUNK_UNKNOWN: if (wpi->is_partial_) goto Fail; // Encountered an unknown chunk // before some image chunks. if (ChunkSetNth(&subchunk, &wpi->unknown_, 0) != WEBP_MUX_OK) goto Fail; break; default: goto Fail; break; } subchunk_size = ChunkDiskSize(&subchunk); bytes += subchunk_size; size -= subchunk_size; } if (wpi->is_partial_) goto Fail; return 1; Fail: ChunkRelease(&subchunk); return 0; } //------------------------------------------------------------------------------ // Create a mux object from WebP-RIFF data. WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data, int version) { size_t riff_size; uint32_t tag; const uint8_t* end; WebPMux* mux = NULL; WebPMuxImage* wpi = NULL; const uint8_t* data; size_t size; WebPChunk chunk; ChunkInit(&chunk); // Sanity checks. if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) { return NULL; // version mismatch } if (bitstream == NULL) return NULL; data = bitstream->bytes; size = bitstream->size; if (data == NULL) return NULL; if (size < RIFF_HEADER_SIZE) return NULL; if (GetLE32(data + 0) != MKFOURCC('R', 'I', 'F', 'F') || GetLE32(data + CHUNK_HEADER_SIZE) != MKFOURCC('W', 'E', 'B', 'P')) { return NULL; } mux = WebPMuxNew(); if (mux == NULL) return NULL; if (size < RIFF_HEADER_SIZE + TAG_SIZE) goto Err; tag = GetLE32(data + RIFF_HEADER_SIZE); if (tag != kChunks[IDX_VP8].tag && tag != kChunks[IDX_VP8L].tag && tag != kChunks[IDX_VP8X].tag) { goto Err; // First chunk should be VP8, VP8L or VP8X. } riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE)); if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) { goto Err; } else { if (riff_size < size) { // Redundant data after last chunk. size = riff_size; // To make sure we don't read any data beyond mux_size. } } end = data + size; data += RIFF_HEADER_SIZE; size -= RIFF_HEADER_SIZE; wpi = (WebPMuxImage*)malloc(sizeof(*wpi)); if (wpi == NULL) goto Err; MuxImageInit(wpi); // Loop over chunks. while (data != end) { size_t data_size; WebPChunkId id; WebPChunk** chunk_list; if (ChunkVerifyAndAssign(&chunk, data, size, riff_size, copy_data) != WEBP_MUX_OK) { goto Err; } data_size = ChunkDiskSize(&chunk); id = ChunkGetIdFromTag(chunk.tag_); switch (id) { case WEBP_CHUNK_ALPHA: if (wpi->alpha_ != NULL) goto Err; // Consecutive ALPH chunks. if (ChunkSetNth(&chunk, &wpi->alpha_, 1) != WEBP_MUX_OK) goto Err; wpi->is_partial_ = 1; // Waiting for a VP8 chunk. break; case WEBP_CHUNK_IMAGE: if (ChunkSetNth(&chunk, &wpi->img_, 1) != WEBP_MUX_OK) goto Err; if (!MuxImageFinalize(wpi)) goto Err; wpi->is_partial_ = 0; // wpi is completely filled. PushImage: // Add this to mux->images_ list. if (MuxImagePush(wpi, &mux->images_) != WEBP_MUX_OK) goto Err; MuxImageInit(wpi); // Reset for reading next image. break; case WEBP_CHUNK_ANMF: #ifdef WEBP_EXPERIMENTAL_FEATURES case WEBP_CHUNK_FRGM: #endif if (wpi->is_partial_) goto Err; // Previous wpi is still incomplete. if (!MuxImageParse(&chunk, copy_data, wpi)) goto Err; ChunkRelease(&chunk); goto PushImage; break; default: // A non-image chunk. if (wpi->is_partial_) goto Err; // Encountered a non-image chunk before // getting all chunks of an image. chunk_list = MuxGetChunkListFromId(mux, id); // List to add this chunk. if (ChunkSetNth(&chunk, chunk_list, 0) != WEBP_MUX_OK) goto Err; break; } data += data_size; size -= data_size; ChunkInit(&chunk); } // Validate mux if complete. if (MuxValidate(mux) != WEBP_MUX_OK) goto Err; MuxImageDelete(wpi); return mux; // All OK; Err: // Something bad happened. ChunkRelease(&chunk); MuxImageDelete(wpi); WebPMuxDelete(mux); return NULL; } //------------------------------------------------------------------------------ // Get API(s). // Validates that the given mux has a single image. static WebPMuxError ValidateForSingleImage(const WebPMux* const mux) { const int num_images = MuxImageCount(mux->images_, WEBP_CHUNK_IMAGE); const int num_frames = MuxImageCount(mux->images_, WEBP_CHUNK_ANMF); const int num_fragments = MuxImageCount(mux->images_, WEBP_CHUNK_FRGM); if (num_images == 0) { // No images in mux. return WEBP_MUX_NOT_FOUND; } else if (num_images == 1 && num_frames == 0 && num_fragments == 0) { // Valid case (single image). return WEBP_MUX_OK; } else { // Frame/Fragment case OR an invalid mux. return WEBP_MUX_INVALID_ARGUMENT; } } // Get the canvas width, height and flags after validating that VP8X/VP8/VP8L // chunk and canvas size are valid. static WebPMuxError MuxGetCanvasInfo(const WebPMux* const mux, int* width, int* height, uint32_t* flags) { int w, h; uint32_t f = 0; WebPData data; assert(mux != NULL); // Check if VP8X chunk is present. if (MuxGet(mux, IDX_VP8X, 1, &data) == WEBP_MUX_OK) { if (data.size < VP8X_CHUNK_SIZE) return WEBP_MUX_BAD_DATA; f = GetLE32(data.bytes + 0); w = GetLE24(data.bytes + 4) + 1; h = GetLE24(data.bytes + 7) + 1; } else { // Single image case. const WebPMuxImage* const wpi = mux->images_; WebPMuxError err = ValidateForSingleImage(mux); if (err != WEBP_MUX_OK) return err; assert(wpi != NULL); w = wpi->width_; h = wpi->height_; if (wpi->has_alpha_) f |= ALPHA_FLAG; } if (w * (uint64_t)h >= MAX_IMAGE_AREA) return WEBP_MUX_BAD_DATA; if (width != NULL) *width = w; if (height != NULL) *height = h; if (flags != NULL) *flags = f; return WEBP_MUX_OK; } WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux, int* width, int* height) { if (mux == NULL || width == NULL || height == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } return MuxGetCanvasInfo(mux, width, height, NULL); } WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) { if (mux == NULL || flags == NULL) return WEBP_MUX_INVALID_ARGUMENT; return MuxGetCanvasInfo(mux, NULL, NULL, flags); } static uint8_t* EmitVP8XChunk(uint8_t* const dst, int width, int height, uint32_t flags) { const size_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE; assert(width >= 1 && height >= 1); assert(width <= MAX_CANVAS_SIZE && height <= MAX_CANVAS_SIZE); assert(width * (uint64_t)height < MAX_IMAGE_AREA); PutLE32(dst, MKFOURCC('V', 'P', '8', 'X')); PutLE32(dst + TAG_SIZE, VP8X_CHUNK_SIZE); PutLE32(dst + CHUNK_HEADER_SIZE, flags); PutLE24(dst + CHUNK_HEADER_SIZE + 4, width - 1); PutLE24(dst + CHUNK_HEADER_SIZE + 7, height - 1); return dst + vp8x_size; } // Assemble a single image WebP bitstream from 'wpi'. static WebPMuxError SynthesizeBitstream(const WebPMuxImage* const wpi, WebPData* const bitstream) { uint8_t* dst; // Allocate data. const int need_vp8x = (wpi->alpha_ != NULL); const size_t vp8x_size = need_vp8x ? CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE : 0; const size_t alpha_size = need_vp8x ? ChunkDiskSize(wpi->alpha_) : 0; // Note: No need to output ANMF/FRGM chunk for a single image. const size_t size = RIFF_HEADER_SIZE + vp8x_size + alpha_size + ChunkDiskSize(wpi->img_); uint8_t* const data = (uint8_t*)malloc(size); if (data == NULL) return WEBP_MUX_MEMORY_ERROR; // Main RIFF header. dst = MuxEmitRiffHeader(data, size); if (need_vp8x) { dst = EmitVP8XChunk(dst, wpi->width_, wpi->height_, ALPHA_FLAG); // VP8X. dst = ChunkListEmit(wpi->alpha_, dst); // ALPH. } // Bitstream. dst = ChunkListEmit(wpi->img_, dst); assert(dst == data + size); // Output. bitstream->bytes = data; bitstream->size = size; return WEBP_MUX_OK; } WebPMuxError WebPMuxGetChunk(const WebPMux* mux, const char fourcc[4], WebPData* chunk_data) { CHUNK_INDEX idx; if (mux == NULL || fourcc == NULL || chunk_data == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } idx = ChunkGetIndexFromFourCC(fourcc); if (IsWPI(kChunks[idx].id)) { // An image chunk. return WEBP_MUX_INVALID_ARGUMENT; } else if (idx != IDX_UNKNOWN) { // A known chunk type. return MuxGet(mux, idx, 1, chunk_data); } else { // An unknown chunk type. const WebPChunk* const chunk = ChunkSearchList(mux->unknown_, 1, ChunkGetTagFromFourCC(fourcc)); if (chunk == NULL) return WEBP_MUX_NOT_FOUND; *chunk_data = chunk->data_; return WEBP_MUX_OK; } } static WebPMuxError MuxGetImageInternal(const WebPMuxImage* const wpi, WebPMuxFrameInfo* const info) { // Set some defaults for unrelated fields. info->x_offset = 0; info->y_offset = 0; info->duration = 1; info->dispose_method = WEBP_MUX_DISPOSE_NONE; info->blend_method = WEBP_MUX_BLEND; // Extract data for related fields. info->id = ChunkGetIdFromTag(wpi->img_->tag_); return SynthesizeBitstream(wpi, &info->bitstream); } static WebPMuxError MuxGetFrameFragmentInternal(const WebPMuxImage* const wpi, WebPMuxFrameInfo* const frame) { const int is_frame = (wpi->header_->tag_ == kChunks[IDX_ANMF].tag); const CHUNK_INDEX idx = is_frame ? IDX_ANMF : IDX_FRGM; const WebPData* frame_frgm_data; #ifndef WEBP_EXPERIMENTAL_FEATURES if (!is_frame) return WEBP_MUX_INVALID_ARGUMENT; #endif assert(wpi->header_ != NULL); // Already checked by WebPMuxGetFrame(). // Get frame/fragment chunk. frame_frgm_data = &wpi->header_->data_; if (frame_frgm_data->size < kChunks[idx].size) return WEBP_MUX_BAD_DATA; // Extract info. frame->x_offset = 2 * GetLE24(frame_frgm_data->bytes + 0); frame->y_offset = 2 * GetLE24(frame_frgm_data->bytes + 3); if (is_frame) { const uint8_t bits = frame_frgm_data->bytes[15]; frame->duration = GetLE24(frame_frgm_data->bytes + 12); frame->dispose_method = (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; frame->blend_method = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND; } else { // Defaults for unused values. frame->duration = 1; frame->dispose_method = WEBP_MUX_DISPOSE_NONE; frame->blend_method = WEBP_MUX_BLEND; } frame->id = ChunkGetIdFromTag(wpi->header_->tag_); return SynthesizeBitstream(wpi, &frame->bitstream); } WebPMuxError WebPMuxGetFrame( const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame) { WebPMuxError err; WebPMuxImage* wpi; // Sanity checks. if (mux == NULL || frame == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } // Get the nth WebPMuxImage. err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, nth, &wpi); if (err != WEBP_MUX_OK) return err; // Get frame info. if (wpi->header_ == NULL) { return MuxGetImageInternal(wpi, frame); } else { return MuxGetFrameFragmentInternal(wpi, frame); } } WebPMuxError WebPMuxGetAnimationParams(const WebPMux* mux, WebPMuxAnimParams* params) { WebPData anim; WebPMuxError err; if (mux == NULL || params == NULL) return WEBP_MUX_INVALID_ARGUMENT; err = MuxGet(mux, IDX_ANIM, 1, &anim); if (err != WEBP_MUX_OK) return err; if (anim.size < kChunks[WEBP_CHUNK_ANIM].size) return WEBP_MUX_BAD_DATA; params->bgcolor = GetLE32(anim.bytes); params->loop_count = GetLE16(anim.bytes + 4); return WEBP_MUX_OK; } // Get chunk index from chunk id. Returns IDX_NIL if not found. static CHUNK_INDEX ChunkGetIndexFromId(WebPChunkId id) { int i; for (i = 0; kChunks[i].id != WEBP_CHUNK_NIL; ++i) { if (id == kChunks[i].id) return (CHUNK_INDEX)i; } return IDX_NIL; } // Count number of chunks matching 'tag' in the 'chunk_list'. // If tag == NIL_TAG, any tag will be matched. static int CountChunks(const WebPChunk* const chunk_list, uint32_t tag) { int count = 0; const WebPChunk* current; for (current = chunk_list; current != NULL; current = current->next_) { if (tag == NIL_TAG || current->tag_ == tag) { count++; // Count chunks whose tags match. } } return count; } WebPMuxError WebPMuxNumChunks(const WebPMux* mux, WebPChunkId id, int* num_elements) { if (mux == NULL || num_elements == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } if (IsWPI(id)) { *num_elements = MuxImageCount(mux->images_, id); } else { WebPChunk* const* chunk_list = MuxGetChunkListFromId(mux, id); const CHUNK_INDEX idx = ChunkGetIndexFromId(id); *num_elements = CountChunks(*chunk_list, kChunks[idx].tag); } return WEBP_MUX_OK; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/mux/libwebpmux.pc.in0000644000014400001440000000042712255002107014553 0ustar prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libwebpmux Description: Library for manipulating the WebP graphics format container Version: @PACKAGE_VERSION@ Requires: libwebp >= 0.2.0 Cflags: -I${includedir} Libs: -L${libdir} -lwebpmux libwebp-0.4.0/src/mux/muxi.h0000644000014400001440000001646512255002107012610 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Internal header for mux library. // // Author: Urvang (urvang@google.com) #ifndef WEBP_MUX_MUXI_H_ #define WEBP_MUX_MUXI_H_ #include #include "../dec/vp8i.h" #include "../dec/vp8li.h" #include "../webp/mux.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Defines and constants. #define MUX_MAJ_VERSION 0 #define MUX_MIN_VERSION 2 #define MUX_REV_VERSION 0 // Chunk object. typedef struct WebPChunk WebPChunk; struct WebPChunk { uint32_t tag_; int owner_; // True if *data_ memory is owned internally. // VP8X, ANIM, and other internally created chunks // like ANMF/FRGM are always owned. WebPData data_; WebPChunk* next_; }; // MuxImage object. Store a full WebP image (including ANMF/FRGM chunk, ALPH // chunk and VP8/VP8L chunk), typedef struct WebPMuxImage WebPMuxImage; struct WebPMuxImage { WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM. WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA. WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE. WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN. int width_; int height_; int has_alpha_; // Through ALPH chunk or as part of VP8L. int is_partial_; // True if only some of the chunks are filled. WebPMuxImage* next_; }; // Main mux object. Stores data chunks. struct WebPMux { WebPMuxImage* images_; WebPChunk* iccp_; WebPChunk* exif_; WebPChunk* xmp_; WebPChunk* anim_; WebPChunk* vp8x_; WebPChunk* unknown_; }; // CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only. // Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to // allow two different chunks to have the same id (e.g. WebPChunkId // 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L'). typedef enum { IDX_VP8X = 0, IDX_ICCP, IDX_ANIM, IDX_ANMF, IDX_FRGM, IDX_ALPHA, IDX_VP8, IDX_VP8L, IDX_EXIF, IDX_XMP, IDX_UNKNOWN, IDX_NIL, IDX_LAST_CHUNK } CHUNK_INDEX; #define NIL_TAG 0x00000000u // To signal void chunk. typedef struct { uint32_t tag; WebPChunkId id; uint32_t size; } ChunkInfo; extern const ChunkInfo kChunks[IDX_LAST_CHUNK]; //------------------------------------------------------------------------------ // Chunk object management. // Initialize. void ChunkInit(WebPChunk* const chunk); // Get chunk index from chunk tag. Returns IDX_UNKNOWN if not found. CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag); // Get chunk id from chunk tag. Returns WEBP_CHUNK_UNKNOWN if not found. WebPChunkId ChunkGetIdFromTag(uint32_t tag); // Convert a fourcc string to a tag. uint32_t ChunkGetTagFromFourCC(const char fourcc[4]); // Get chunk index from fourcc. Returns IDX_UNKNOWN if given fourcc is unknown. CHUNK_INDEX ChunkGetIndexFromFourCC(const char fourcc[4]); // Search for nth chunk with given 'tag' in the chunk list. // nth = 0 means "last of the list". WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag); // Fill the chunk with the given data. WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data, int copy_data, uint32_t tag); // Sets 'chunk' at nth position in the 'chunk_list'. // nth = 0 has the special meaning "last of the list". // On success ownership is transferred from 'chunk' to the 'chunk_list'. WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list, uint32_t nth); // Releases chunk and returns chunk->next_. WebPChunk* ChunkRelease(WebPChunk* const chunk); // Deletes given chunk & returns chunk->next_. WebPChunk* ChunkDelete(WebPChunk* const chunk); // Deletes all chunks in the given chunk list. void ChunkListDelete(WebPChunk** const chunk_list); // Returns size of the chunk including chunk header and padding byte (if any). static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) { return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U); } // Size of a chunk including header and padding. static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) { const size_t data_size = chunk->data_.size; assert(data_size < MAX_CHUNK_PAYLOAD); return SizeWithPadding(data_size); } // Total size of a list of chunks. size_t ChunkListDiskSize(const WebPChunk* chunk_list); // Write out the given list of chunks into 'dst'. uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst); //------------------------------------------------------------------------------ // MuxImage object management. // Initialize. void MuxImageInit(WebPMuxImage* const wpi); // Releases image 'wpi' and returns wpi->next. WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi); // Delete image 'wpi' and return the next image in the list or NULL. // 'wpi' can be NULL. WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi); // Count number of images matching the given tag id in the 'wpi_list'. // If id == WEBP_CHUNK_NIL, all images will be matched. int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id); // Update width/height/has_alpha info from chunks within wpi. // Also remove ALPH chunk if not needed. int MuxImageFinalize(WebPMuxImage* const wpi); // Check if given ID corresponds to an image related chunk. static WEBP_INLINE int IsWPI(WebPChunkId id) { switch (id) { case WEBP_CHUNK_ANMF: case WEBP_CHUNK_FRGM: case WEBP_CHUNK_ALPHA: case WEBP_CHUNK_IMAGE: return 1; default: return 0; } } // Pushes 'wpi' at the end of 'wpi_list'. WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list); // Delete nth image in the image list. WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth); // Get nth image in the image list. WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth, WebPMuxImage** wpi); // Total size of the given image. size_t MuxImageDiskSize(const WebPMuxImage* const wpi); // Write out the given image into 'dst'. uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst); //------------------------------------------------------------------------------ // Helper methods for mux. // Checks if the given image list contains at least one image with alpha. int MuxHasAlpha(const WebPMuxImage* images); // Write out RIFF header into 'data', given total data size 'size'. uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size); // Returns the list where chunk with given ID is to be inserted in mux. WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id); // Validates the given mux object. WebPMuxError MuxValidate(const WebPMux* const mux); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_MUX_MUXI_H_ */ libwebp-0.4.0/src/mux/muxedit.c0000644000014400001440000005273012255002107013273 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Set and delete APIs for mux. // // Authors: Urvang (urvang@google.com) // Vikas (vikasa@google.com) #include #include "./muxi.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ // Life of a mux object. static void MuxInit(WebPMux* const mux) { if (mux == NULL) return; memset(mux, 0, sizeof(*mux)); } WebPMux* WebPNewInternal(int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) { return NULL; } else { WebPMux* const mux = (WebPMux*)malloc(sizeof(WebPMux)); // If mux is NULL MuxInit is a noop. MuxInit(mux); return mux; } } // Delete all images in 'wpi_list'. static void DeleteAllImages(WebPMuxImage** const wpi_list) { while (*wpi_list != NULL) { *wpi_list = MuxImageDelete(*wpi_list); } } static void MuxRelease(WebPMux* const mux) { if (mux == NULL) return; DeleteAllImages(&mux->images_); ChunkListDelete(&mux->vp8x_); ChunkListDelete(&mux->iccp_); ChunkListDelete(&mux->anim_); ChunkListDelete(&mux->exif_); ChunkListDelete(&mux->xmp_); ChunkListDelete(&mux->unknown_); } void WebPMuxDelete(WebPMux* mux) { // If mux is NULL MuxRelease is a noop. MuxRelease(mux); free(mux); } //------------------------------------------------------------------------------ // Helper method(s). // Handy MACRO, makes MuxSet() very symmetric to MuxGet(). #define SWITCH_ID_LIST(INDEX, LIST) \ if (idx == (INDEX)) { \ err = ChunkAssignData(&chunk, data, copy_data, tag); \ if (err == WEBP_MUX_OK) { \ err = ChunkSetNth(&chunk, (LIST), nth); \ } \ return err; \ } static WebPMuxError MuxSet(WebPMux* const mux, uint32_t tag, uint32_t nth, const WebPData* const data, int copy_data) { WebPChunk chunk; WebPMuxError err = WEBP_MUX_NOT_FOUND; const CHUNK_INDEX idx = ChunkGetIndexFromTag(tag); assert(mux != NULL); assert(!IsWPI(kChunks[idx].id)); ChunkInit(&chunk); SWITCH_ID_LIST(IDX_VP8X, &mux->vp8x_); SWITCH_ID_LIST(IDX_ICCP, &mux->iccp_); SWITCH_ID_LIST(IDX_ANIM, &mux->anim_); SWITCH_ID_LIST(IDX_EXIF, &mux->exif_); SWITCH_ID_LIST(IDX_XMP, &mux->xmp_); SWITCH_ID_LIST(IDX_UNKNOWN, &mux->unknown_); return err; } #undef SWITCH_ID_LIST // Create data for frame/fragment given image data, offsets and duration. static WebPMuxError CreateFrameFragmentData( int width, int height, const WebPMuxFrameInfo* const info, int is_frame, WebPData* const frame_frgm) { uint8_t* frame_frgm_bytes; const size_t frame_frgm_size = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].size; assert(width > 0 && height > 0 && info->duration >= 0); assert(info->dispose_method == (info->dispose_method & 1)); // Note: assertion on upper bounds is done in PutLE24(). frame_frgm_bytes = (uint8_t*)malloc(frame_frgm_size); if (frame_frgm_bytes == NULL) return WEBP_MUX_MEMORY_ERROR; PutLE24(frame_frgm_bytes + 0, info->x_offset / 2); PutLE24(frame_frgm_bytes + 3, info->y_offset / 2); if (is_frame) { PutLE24(frame_frgm_bytes + 6, width - 1); PutLE24(frame_frgm_bytes + 9, height - 1); PutLE24(frame_frgm_bytes + 12, info->duration); frame_frgm_bytes[15] = (info->blend_method == WEBP_MUX_NO_BLEND ? 2 : 0) | (info->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ? 1 : 0); } frame_frgm->bytes = frame_frgm_bytes; frame_frgm->size = frame_frgm_size; return WEBP_MUX_OK; } // Outputs image data given a bitstream. The bitstream can either be a // single-image WebP file or raw VP8/VP8L data. // Also outputs 'is_lossless' to be true if the given bitstream is lossless. static WebPMuxError GetImageData(const WebPData* const bitstream, WebPData* const image, WebPData* const alpha, int* const is_lossless) { WebPDataInit(alpha); // Default: no alpha. if (bitstream->size < TAG_SIZE || memcmp(bitstream->bytes, "RIFF", TAG_SIZE)) { // It is NOT webp file data. Return input data as is. *image = *bitstream; } else { // It is webp file data. Extract image data from it. const WebPMuxImage* wpi; WebPMux* const mux = WebPMuxCreate(bitstream, 0); if (mux == NULL) return WEBP_MUX_BAD_DATA; wpi = mux->images_; assert(wpi != NULL && wpi->img_ != NULL); *image = wpi->img_->data_; if (wpi->alpha_ != NULL) { *alpha = wpi->alpha_->data_; } WebPMuxDelete(mux); } *is_lossless = VP8LCheckSignature(image->bytes, image->size); return WEBP_MUX_OK; } static WebPMuxError DeleteChunks(WebPChunk** chunk_list, uint32_t tag) { WebPMuxError err = WEBP_MUX_NOT_FOUND; assert(chunk_list); while (*chunk_list) { WebPChunk* const chunk = *chunk_list; if (chunk->tag_ == tag) { *chunk_list = ChunkDelete(chunk); err = WEBP_MUX_OK; } else { chunk_list = &chunk->next_; } } return err; } static WebPMuxError MuxDeleteAllNamedData(WebPMux* const mux, uint32_t tag) { const WebPChunkId id = ChunkGetIdFromTag(tag); assert(mux != NULL); if (IsWPI(id)) return WEBP_MUX_INVALID_ARGUMENT; return DeleteChunks(MuxGetChunkListFromId(mux, id), tag); } //------------------------------------------------------------------------------ // Set API(s). WebPMuxError WebPMuxSetChunk(WebPMux* mux, const char fourcc[4], const WebPData* chunk_data, int copy_data) { uint32_t tag; WebPMuxError err; if (mux == NULL || fourcc == NULL || chunk_data == NULL || chunk_data->bytes == NULL || chunk_data->size > MAX_CHUNK_PAYLOAD) { return WEBP_MUX_INVALID_ARGUMENT; } tag = ChunkGetTagFromFourCC(fourcc); // Delete existing chunk(s) with the same 'fourcc'. err = MuxDeleteAllNamedData(mux, tag); if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err; // Add the given chunk. return MuxSet(mux, tag, 1, chunk_data, copy_data); } // Creates a chunk from given 'data' and sets it as 1st chunk in 'chunk_list'. static WebPMuxError AddDataToChunkList( const WebPData* const data, int copy_data, uint32_t tag, WebPChunk** chunk_list) { WebPChunk chunk; WebPMuxError err; ChunkInit(&chunk); err = ChunkAssignData(&chunk, data, copy_data, tag); if (err != WEBP_MUX_OK) goto Err; err = ChunkSetNth(&chunk, chunk_list, 1); if (err != WEBP_MUX_OK) goto Err; return WEBP_MUX_OK; Err: ChunkRelease(&chunk); return err; } // Extracts image & alpha data from the given bitstream and then sets wpi.alpha_ // and wpi.img_ appropriately. static WebPMuxError SetAlphaAndImageChunks( const WebPData* const bitstream, int copy_data, WebPMuxImage* const wpi) { int is_lossless = 0; WebPData image, alpha; WebPMuxError err = GetImageData(bitstream, &image, &alpha, &is_lossless); const int image_tag = is_lossless ? kChunks[IDX_VP8L].tag : kChunks[IDX_VP8].tag; if (err != WEBP_MUX_OK) return err; if (alpha.bytes != NULL) { err = AddDataToChunkList(&alpha, copy_data, kChunks[IDX_ALPHA].tag, &wpi->alpha_); if (err != WEBP_MUX_OK) return err; } err = AddDataToChunkList(&image, copy_data, image_tag, &wpi->img_); if (err != WEBP_MUX_OK) return err; return MuxImageFinalize(wpi) ? WEBP_MUX_OK : WEBP_MUX_INVALID_ARGUMENT; } WebPMuxError WebPMuxSetImage(WebPMux* mux, const WebPData* bitstream, int copy_data) { WebPMuxImage wpi; WebPMuxError err; // Sanity checks. if (mux == NULL || bitstream == NULL || bitstream->bytes == NULL || bitstream->size > MAX_CHUNK_PAYLOAD) { return WEBP_MUX_INVALID_ARGUMENT; } if (mux->images_ != NULL) { // Only one 'simple image' can be added in mux. So, remove present images. DeleteAllImages(&mux->images_); } MuxImageInit(&wpi); err = SetAlphaAndImageChunks(bitstream, copy_data, &wpi); if (err != WEBP_MUX_OK) goto Err; // Add this WebPMuxImage to mux. err = MuxImagePush(&wpi, &mux->images_); if (err != WEBP_MUX_OK) goto Err; // All is well. return WEBP_MUX_OK; Err: // Something bad happened. MuxImageRelease(&wpi); return err; } WebPMuxError WebPMuxPushFrame(WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data) { WebPMuxImage wpi; WebPMuxError err; int is_frame; const WebPData* const bitstream = &frame->bitstream; // Sanity checks. if (mux == NULL || frame == NULL) return WEBP_MUX_INVALID_ARGUMENT; is_frame = (frame->id == WEBP_CHUNK_ANMF); if (!(is_frame || (frame->id == WEBP_CHUNK_FRGM))) { return WEBP_MUX_INVALID_ARGUMENT; } #ifndef WEBP_EXPERIMENTAL_FEATURES if (frame->id == WEBP_CHUNK_FRGM) { // disabled for now. return WEBP_MUX_INVALID_ARGUMENT; } #endif if (bitstream->bytes == NULL || bitstream->size > MAX_CHUNK_PAYLOAD) { return WEBP_MUX_INVALID_ARGUMENT; } if (mux->images_ != NULL) { const WebPMuxImage* const image = mux->images_; const uint32_t image_id = (image->header_ != NULL) ? ChunkGetIdFromTag(image->header_->tag_) : WEBP_CHUNK_IMAGE; if (image_id != frame->id) { return WEBP_MUX_INVALID_ARGUMENT; // Conflicting frame types. } } MuxImageInit(&wpi); err = SetAlphaAndImageChunks(bitstream, copy_data, &wpi); if (err != WEBP_MUX_OK) goto Err; assert(wpi.img_ != NULL); // As SetAlphaAndImageChunks() was successful. { WebPData frame_frgm; const uint32_t tag = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].tag; WebPMuxFrameInfo tmp = *frame; tmp.x_offset &= ~1; // Snap offsets to even. tmp.y_offset &= ~1; if (!is_frame) { // Reset unused values. tmp.duration = 1; tmp.dispose_method = WEBP_MUX_DISPOSE_NONE; tmp.blend_method = WEBP_MUX_BLEND; } if (tmp.x_offset < 0 || tmp.x_offset >= MAX_POSITION_OFFSET || tmp.y_offset < 0 || tmp.y_offset >= MAX_POSITION_OFFSET || (tmp.duration < 0 || tmp.duration >= MAX_DURATION) || tmp.dispose_method != (tmp.dispose_method & 1)) { err = WEBP_MUX_INVALID_ARGUMENT; goto Err; } err = CreateFrameFragmentData(wpi.width_, wpi.height_, &tmp, is_frame, &frame_frgm); if (err != WEBP_MUX_OK) goto Err; // Add frame/fragment chunk (with copy_data = 1). err = AddDataToChunkList(&frame_frgm, 1, tag, &wpi.header_); WebPDataClear(&frame_frgm); // frame_frgm owned by wpi.header_ now. if (err != WEBP_MUX_OK) goto Err; } // Add this WebPMuxImage to mux. err = MuxImagePush(&wpi, &mux->images_); if (err != WEBP_MUX_OK) goto Err; // All is well. return WEBP_MUX_OK; Err: // Something bad happened. MuxImageRelease(&wpi); return err; } WebPMuxError WebPMuxSetAnimationParams(WebPMux* mux, const WebPMuxAnimParams* params) { WebPMuxError err; uint8_t data[ANIM_CHUNK_SIZE]; const WebPData anim = { data, ANIM_CHUNK_SIZE }; if (mux == NULL || params == NULL) return WEBP_MUX_INVALID_ARGUMENT; if (params->loop_count < 0 || params->loop_count >= MAX_LOOP_COUNT) { return WEBP_MUX_INVALID_ARGUMENT; } // Delete any existing ANIM chunk(s). err = MuxDeleteAllNamedData(mux, kChunks[IDX_ANIM].tag); if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err; // Set the animation parameters. PutLE32(data, params->bgcolor); PutLE16(data + 4, params->loop_count); return MuxSet(mux, kChunks[IDX_ANIM].tag, 1, &anim, 1); } //------------------------------------------------------------------------------ // Delete API(s). WebPMuxError WebPMuxDeleteChunk(WebPMux* mux, const char fourcc[4]) { if (mux == NULL || fourcc == NULL) return WEBP_MUX_INVALID_ARGUMENT; return MuxDeleteAllNamedData(mux, ChunkGetTagFromFourCC(fourcc)); } WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth) { if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT; return MuxImageDeleteNth(&mux->images_, nth); } //------------------------------------------------------------------------------ // Assembly of the WebP RIFF file. static WebPMuxError GetFrameFragmentInfo( const WebPChunk* const frame_frgm_chunk, int* const x_offset, int* const y_offset, int* const duration) { const uint32_t tag = frame_frgm_chunk->tag_; const int is_frame = (tag == kChunks[IDX_ANMF].tag); const WebPData* const data = &frame_frgm_chunk->data_; const size_t expected_data_size = is_frame ? ANMF_CHUNK_SIZE : FRGM_CHUNK_SIZE; assert(frame_frgm_chunk != NULL); assert(tag == kChunks[IDX_ANMF].tag || tag == kChunks[IDX_FRGM].tag); if (data->size != expected_data_size) return WEBP_MUX_INVALID_ARGUMENT; *x_offset = 2 * GetLE24(data->bytes + 0); *y_offset = 2 * GetLE24(data->bytes + 3); if (is_frame) *duration = GetLE24(data->bytes + 12); return WEBP_MUX_OK; } static WebPMuxError GetImageInfo(const WebPMuxImage* const wpi, int* const x_offset, int* const y_offset, int* const duration, int* const width, int* const height) { const WebPChunk* const frame_frgm_chunk = wpi->header_; WebPMuxError err; assert(wpi != NULL); assert(frame_frgm_chunk != NULL); // Get offsets and duration from ANMF/FRGM chunk. err = GetFrameFragmentInfo(frame_frgm_chunk, x_offset, y_offset, duration); if (err != WEBP_MUX_OK) return err; // Get width and height from VP8/VP8L chunk. if (width != NULL) *width = wpi->width_; if (height != NULL) *height = wpi->height_; return WEBP_MUX_OK; } static WebPMuxError GetImageCanvasWidthHeight( const WebPMux* const mux, uint32_t flags, int* const width, int* const height) { WebPMuxImage* wpi = NULL; assert(mux != NULL); assert(width != NULL && height != NULL); wpi = mux->images_; assert(wpi != NULL); assert(wpi->img_ != NULL); if (wpi->next_ != NULL) { int max_x = 0; int max_y = 0; int64_t image_area = 0; // if we have a chain of wpi's, header_ is necessarily set assert(wpi->header_ != NULL); // Aggregate the bounding box for animation frames & fragmented images. for (; wpi != NULL; wpi = wpi->next_) { int x_offset = 0, y_offset = 0, duration = 0, w = 0, h = 0; const WebPMuxError err = GetImageInfo(wpi, &x_offset, &y_offset, &duration, &w, &h); const int max_x_pos = x_offset + w; const int max_y_pos = y_offset + h; if (err != WEBP_MUX_OK) return err; assert(x_offset < MAX_POSITION_OFFSET); assert(y_offset < MAX_POSITION_OFFSET); if (max_x_pos > max_x) max_x = max_x_pos; if (max_y_pos > max_y) max_y = max_y_pos; image_area += w * h; } *width = max_x; *height = max_y; // Crude check to validate that there are no image overlaps/holes for // fragmented images. Check that the aggregated image area for individual // fragments exactly matches the image area of the constructed canvas. // However, the area-match is necessary but not sufficient condition. if ((flags & FRAGMENTS_FLAG) && (image_area != (max_x * max_y))) { *width = 0; *height = 0; return WEBP_MUX_INVALID_ARGUMENT; } } else { // For a single image, canvas dimensions are same as image dimensions. *width = wpi->width_; *height = wpi->height_; } return WEBP_MUX_OK; } // VP8X format: // Total Size : 10, // Flags : 4 bytes, // Width : 3 bytes, // Height : 3 bytes. static WebPMuxError CreateVP8XChunk(WebPMux* const mux) { WebPMuxError err = WEBP_MUX_OK; uint32_t flags = 0; int width = 0; int height = 0; uint8_t data[VP8X_CHUNK_SIZE]; const WebPData vp8x = { data, VP8X_CHUNK_SIZE }; const WebPMuxImage* images = NULL; assert(mux != NULL); images = mux->images_; // First image. if (images == NULL || images->img_ == NULL || images->img_->data_.bytes == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } // If VP8X chunk(s) is(are) already present, remove them (and later add new // VP8X chunk with updated flags). err = MuxDeleteAllNamedData(mux, kChunks[IDX_VP8X].tag); if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err; // Set flags. if (mux->iccp_ != NULL && mux->iccp_->data_.bytes != NULL) { flags |= ICCP_FLAG; } if (mux->exif_ != NULL && mux->exif_->data_.bytes != NULL) { flags |= EXIF_FLAG; } if (mux->xmp_ != NULL && mux->xmp_->data_.bytes != NULL) { flags |= XMP_FLAG; } if (images->header_ != NULL) { if (images->header_->tag_ == kChunks[IDX_FRGM].tag) { // This is a fragmented image. flags |= FRAGMENTS_FLAG; } else if (images->header_->tag_ == kChunks[IDX_ANMF].tag) { // This is an image with animation. flags |= ANIMATION_FLAG; } } if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) { flags |= ALPHA_FLAG; // Some images have an alpha channel. } if (flags == 0) { // For Simple Image, VP8X chunk should not be added. return WEBP_MUX_OK; } err = GetImageCanvasWidthHeight(mux, flags, &width, &height); if (err != WEBP_MUX_OK) return err; if (width <= 0 || height <= 0) { return WEBP_MUX_INVALID_ARGUMENT; } if (width > MAX_CANVAS_SIZE || height > MAX_CANVAS_SIZE) { return WEBP_MUX_INVALID_ARGUMENT; } if (MuxHasAlpha(images)) { // This means some frames explicitly/implicitly contain alpha. // Note: This 'flags' update must NOT be done for a lossless image // without a VP8X chunk! flags |= ALPHA_FLAG; } PutLE32(data + 0, flags); // VP8X chunk flags. PutLE24(data + 4, width - 1); // canvas width. PutLE24(data + 7, height - 1); // canvas height. return MuxSet(mux, kChunks[IDX_VP8X].tag, 1, &vp8x, 1); } // Cleans up 'mux' by removing any unnecessary chunks. static WebPMuxError MuxCleanup(WebPMux* const mux) { int num_frames; int num_fragments; int num_anim_chunks; // If we have an image with single fragment or frame, convert it to a // non-animated non-fragmented image (to avoid writing FRGM/ANMF chunk // unnecessarily). WebPMuxError err = WebPMuxNumChunks(mux, kChunks[IDX_ANMF].id, &num_frames); if (err != WEBP_MUX_OK) return err; err = WebPMuxNumChunks(mux, kChunks[IDX_FRGM].id, &num_fragments); if (err != WEBP_MUX_OK) return err; if (num_frames == 1 || num_fragments == 1) { WebPMuxImage* frame_frag; err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, 1, &frame_frag); assert(err == WEBP_MUX_OK); // We know that one frame/fragment does exist. if (frame_frag->header_ != NULL) { assert(frame_frag->header_->tag_ == kChunks[IDX_ANMF].tag || frame_frag->header_->tag_ == kChunks[IDX_FRGM].tag); ChunkDelete(frame_frag->header_); // Removes ANMF/FRGM chunk. frame_frag->header_ = NULL; } num_frames = 0; num_fragments = 0; } // Remove ANIM chunk if this is a non-animated image. err = WebPMuxNumChunks(mux, kChunks[IDX_ANIM].id, &num_anim_chunks); if (err != WEBP_MUX_OK) return err; if (num_anim_chunks >= 1 && num_frames == 0) { err = MuxDeleteAllNamedData(mux, kChunks[IDX_ANIM].tag); if (err != WEBP_MUX_OK) return err; } return WEBP_MUX_OK; } // Total size of a list of images. static size_t ImageListDiskSize(const WebPMuxImage* wpi_list) { size_t size = 0; while (wpi_list != NULL) { size += MuxImageDiskSize(wpi_list); wpi_list = wpi_list->next_; } return size; } // Write out the given list of images into 'dst'. static uint8_t* ImageListEmit(const WebPMuxImage* wpi_list, uint8_t* dst) { while (wpi_list != NULL) { dst = MuxImageEmit(wpi_list, dst); wpi_list = wpi_list->next_; } return dst; } WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) { size_t size = 0; uint8_t* data = NULL; uint8_t* dst = NULL; WebPMuxError err; if (mux == NULL || assembled_data == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } // Finalize mux. err = MuxCleanup(mux); if (err != WEBP_MUX_OK) return err; err = CreateVP8XChunk(mux); if (err != WEBP_MUX_OK) return err; // Allocate data. size = ChunkListDiskSize(mux->vp8x_) + ChunkListDiskSize(mux->iccp_) + ChunkListDiskSize(mux->anim_) + ImageListDiskSize(mux->images_) + ChunkListDiskSize(mux->exif_) + ChunkListDiskSize(mux->xmp_) + ChunkListDiskSize(mux->unknown_) + RIFF_HEADER_SIZE; data = (uint8_t*)malloc(size); if (data == NULL) return WEBP_MUX_MEMORY_ERROR; // Emit header & chunks. dst = MuxEmitRiffHeader(data, size); dst = ChunkListEmit(mux->vp8x_, dst); dst = ChunkListEmit(mux->iccp_, dst); dst = ChunkListEmit(mux->anim_, dst); dst = ImageListEmit(mux->images_, dst); dst = ChunkListEmit(mux->exif_, dst); dst = ChunkListEmit(mux->xmp_, dst); dst = ChunkListEmit(mux->unknown_, dst); assert(dst == data + size); // Validate mux. err = MuxValidate(mux); if (err != WEBP_MUX_OK) { free(data); data = NULL; size = 0; } // Finalize data. assembled_data->bytes = data; assembled_data->size = size; return err; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/mux/Makefile.am0000644000014400001440000000106712255002107013501 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src lib_LTLIBRARIES = libwebpmux.la libwebpmux_la_SOURCES = libwebpmux_la_SOURCES += muxedit.c libwebpmux_la_SOURCES += muxi.h libwebpmux_la_SOURCES += muxinternal.c libwebpmux_la_SOURCES += muxread.c libwebpmuxinclude_HEADERS = libwebpmuxinclude_HEADERS += ../webp/mux.h libwebpmuxinclude_HEADERS += ../webp/mux_types.h libwebpmuxinclude_HEADERS += ../webp/types.h libwebpmux_la_LIBADD = ../libwebp.la libwebpmux_la_LDFLAGS = -no-undefined -version-info 1:0:0 libwebpmuxincludedir = $(includedir)/webp pkgconfig_DATA = libwebpmux.pc libwebp-0.4.0/src/Makefile.in0000644000014400001440000006666012255206714012725 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ @WANT_MUX_TRUE@am__append_1 = mux @WANT_DEMUX_TRUE@am__append_2 = demux @BUILD_LIBWEBPDECODER_TRUE@am__append_3 = libwebpdecoder.la @BUILD_LIBWEBPDECODER_TRUE@am__append_4 = libwebpdecoder.pc subdir = src DIST_COMMON = $(common_HEADERS) $(libwebpinclude_HEADERS) \ $(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/libwebp.pc.in $(srcdir)/libwebpdecoder.pc.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libwebp.pc libwebpdecoder.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(commondir)" "$(DESTDIR)$(libwebpincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libwebp_la_DEPENDENCIES = dec/libwebpdecode.la dsp/libwebpdsp.la \ enc/libwebpencode.la utils/libwebputils.la am_libwebp_la_OBJECTS = libwebp_la_OBJECTS = $(am_libwebp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libwebp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libwebp_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_LIBWEBPDECODER_TRUE@libwebpdecoder_la_DEPENDENCIES = \ @BUILD_LIBWEBPDECODER_TRUE@ dec/libwebpdecode.la \ @BUILD_LIBWEBPDECODER_TRUE@ dsp/libwebpdspdecode.la \ @BUILD_LIBWEBPDECODER_TRUE@ utils/libwebputilsdecode.la am_libwebpdecoder_la_OBJECTS = libwebpdecoder_la_OBJECTS = $(am_libwebpdecoder_la_OBJECTS) libwebpdecoder_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libwebpdecoder_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILD_LIBWEBPDECODER_TRUE@am_libwebpdecoder_la_rpath = -rpath \ @BUILD_LIBWEBPDECODER_TRUE@ $(libdir) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebp_la_SOURCES) $(libwebpdecoder_la_SOURCES) DIST_SOURCES = $(libwebp_la_SOURCES) $(libwebpdecoder_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive DATA = $(pkgconfig_DATA) HEADERS = $(common_HEADERS) $(libwebpinclude_HEADERS) \ $(noinst_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = dec enc dsp utils . mux demux DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # The mux and demux libraries depend on libwebp, thus the '.' to force the # build order so it's available to them. SUBDIRS = dec enc dsp utils . $(am__append_1) $(am__append_2) AM_CPPFLAGS = -I$(top_srcdir)/src lib_LTLIBRARIES = libwebp.la $(am__append_3) common_HEADERS = webp/decode.h webp/types.h commondir = $(includedir)/webp libwebp_la_SOURCES = libwebpinclude_HEADERS = webp/encode.h noinst_HEADERS = webp/format_constants.h libwebp_la_LIBADD = dec/libwebpdecode.la dsp/libwebpdsp.la \ enc/libwebpencode.la utils/libwebputils.la # Use '-no-undefined' to declare that libwebp does not depend on any libraries # other than the ones listed on the command line, i.e., after linking, it will # not have unresolved symbols. Some platforms (Windows among them) require all # symbols in shared libraries to be resolved at library creation. libwebp_la_LDFLAGS = -no-undefined -version-info 5:0:0 libwebpincludedir = $(includedir)/webp pkgconfig_DATA = libwebp.pc $(am__append_4) @BUILD_LIBWEBPDECODER_TRUE@libwebpdecoder_la_SOURCES = @BUILD_LIBWEBPDECODER_TRUE@libwebpdecoder_la_LIBADD = \ @BUILD_LIBWEBPDECODER_TRUE@ dec/libwebpdecode.la \ @BUILD_LIBWEBPDECODER_TRUE@ dsp/libwebpdspdecode.la \ @BUILD_LIBWEBPDECODER_TRUE@ utils/libwebputilsdecode.la @BUILD_LIBWEBPDECODER_TRUE@libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 1:0:0 all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libwebp.pc: $(top_builddir)/config.status $(srcdir)/libwebp.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ libwebpdecoder.pc: $(top_builddir)/config.status $(srcdir)/libwebpdecoder.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebp.la: $(libwebp_la_OBJECTS) $(libwebp_la_DEPENDENCIES) $(EXTRA_libwebp_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebp_la_LINK) -rpath $(libdir) $(libwebp_la_OBJECTS) $(libwebp_la_LIBADD) $(LIBS) libwebpdecoder.la: $(libwebpdecoder_la_OBJECTS) $(libwebpdecoder_la_DEPENDENCIES) $(EXTRA_libwebpdecoder_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebpdecoder_la_LINK) $(am_libwebpdecoder_la_rpath) $(libwebpdecoder_la_OBJECTS) $(libwebpdecoder_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-commonHEADERS: $(common_HEADERS) @$(NORMAL_INSTALL) test -z "$(commondir)" || $(MKDIR_P) "$(DESTDIR)$(commondir)" @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(commondir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(commondir)" || exit $$?; \ done uninstall-commonHEADERS: @$(NORMAL_UNINSTALL) @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(commondir)'; $(am__uninstall_files_from_dir) install-libwebpincludeHEADERS: $(libwebpinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(libwebpincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libwebpincludedir)" @list='$(libwebpinclude_HEADERS)'; test -n "$(libwebpincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpincludedir)" || exit $$?; \ done uninstall-libwebpincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libwebpinclude_HEADERS)'; test -n "$(libwebpincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libwebpincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(commondir)" "$(DESTDIR)$(libwebpincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive 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-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-commonHEADERS install-libwebpincludeHEADERS \ install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-commonHEADERS uninstall-libLTLIBRARIES \ uninstall-libwebpincludeHEADERS uninstall-pkgconfigDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-commonHEADERS \ 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-libLTLIBRARIES \ install-libwebpincludeHEADERS install-man install-pdf \ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-commonHEADERS \ uninstall-libLTLIBRARIES uninstall-libwebpincludeHEADERS \ uninstall-pkgconfigDATA ${pkgconfig_DATA}: ${top_builddir}/config.status # 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: libwebp-0.4.0/src/enc/0000755000014400001440000000000012255206714011407 5ustar libwebp-0.4.0/src/enc/vp8enci.h0000644000014400001440000005423612255002107013134 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // WebP encoder: internal header. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_ENC_VP8ENCI_H_ #define WEBP_ENC_VP8ENCI_H_ #include // for memcpy() #include "../webp/encode.h" #include "../dsp/dsp.h" #include "../utils/bit_writer.h" #include "../utils/thread.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Various defines and enums // version numbers #define ENC_MAJ_VERSION 0 #define ENC_MIN_VERSION 4 #define ENC_REV_VERSION 0 // intra prediction modes enum { B_DC_PRED = 0, // 4x4 modes B_TM_PRED = 1, B_VE_PRED = 2, B_HE_PRED = 3, B_RD_PRED = 4, B_VR_PRED = 5, B_LD_PRED = 6, B_VL_PRED = 7, B_HD_PRED = 8, B_HU_PRED = 9, NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED, // = 10 // Luma16 or UV modes DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED, H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED, NUM_PRED_MODES = 4 }; enum { NUM_MB_SEGMENTS = 4, MAX_NUM_PARTITIONS = 8, NUM_TYPES = 4, // 0: i16-AC, 1: i16-DC, 2:chroma-AC, 3:i4-AC NUM_BANDS = 8, NUM_CTX = 3, NUM_PROBAS = 11, MAX_LF_LEVELS = 64, // Maximum loop filter level MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost MAX_LEVEL = 2047 // max level (note: max codable is 2047 + 67) }; typedef enum { // Rate-distortion optimization levels RD_OPT_NONE = 0, // no rd-opt RD_OPT_BASIC = 1, // basic scoring (no trellis) RD_OPT_TRELLIS = 2, // perform trellis-quant on the final decision only RD_OPT_TRELLIS_ALL = 3 // trellis-quant for every scoring (much slower) } VP8RDLevel; // YUV-cache parameters. Cache is 16-pixels wide. // The original or reconstructed samples can be accessed using VP8Scan[] // The predicted blocks can be accessed using offsets to yuv_p_ and // the arrays VP8*ModeOffsets[]; // +----+ YUV Samples area. See VP8Scan[] for accessing the blocks. // Y_OFF |YYYY| <- original samples ('yuv_in_') // |YYYY| // |YYYY| // |YYYY| // U_OFF |UUVV| V_OFF (=U_OFF + 8) // |UUVV| // +----+ // Y_OFF |YYYY| <- compressed/decoded samples ('yuv_out_') // |YYYY| There are two buffers like this ('yuv_out_'/'yuv_out2_') // |YYYY| // |YYYY| // U_OFF |UUVV| V_OFF // |UUVV| // x2 (for yuv_out2_) // +----+ Prediction area ('yuv_p_', size = PRED_SIZE) // I16DC16 |YYYY| Intra16 predictions (16x16 block each) // |YYYY| // |YYYY| // |YYYY| // I16TM16 |YYYY| // |YYYY| // |YYYY| // |YYYY| // I16VE16 |YYYY| // |YYYY| // |YYYY| // |YYYY| // I16HE16 |YYYY| // |YYYY| // |YYYY| // |YYYY| // +----+ Chroma U/V predictions (16x8 block each) // C8DC8 |UUVV| // |UUVV| // C8TM8 |UUVV| // |UUVV| // C8VE8 |UUVV| // |UUVV| // C8HE8 |UUVV| // |UUVV| // +----+ Intra 4x4 predictions (4x4 block each) // |YYYY| I4DC4 I4TM4 I4VE4 I4HE4 // |YYYY| I4RD4 I4VR4 I4LD4 I4VL4 // |YY..| I4HD4 I4HU4 I4TMP // +----+ #define BPS 16 // this is the common stride #define Y_SIZE (BPS * 16) #define UV_SIZE (BPS * 8) #define YUV_SIZE (Y_SIZE + UV_SIZE) #define PRED_SIZE (6 * 16 * BPS + 12 * BPS) #define Y_OFF (0) #define U_OFF (Y_SIZE) #define V_OFF (U_OFF + 8) #define ALIGN_CST 15 #define DO_ALIGN(PTR) ((uintptr_t)((PTR) + ALIGN_CST) & ~ALIGN_CST) extern const int VP8Scan[16 + 4 + 4]; // in quant.c extern const int VP8UVModeOffsets[4]; // in analyze.c extern const int VP8I16ModeOffsets[4]; extern const int VP8I4ModeOffsets[NUM_BMODES]; // Layout of prediction blocks // intra 16x16 #define I16DC16 (0 * 16 * BPS) #define I16TM16 (1 * 16 * BPS) #define I16VE16 (2 * 16 * BPS) #define I16HE16 (3 * 16 * BPS) // chroma 8x8, two U/V blocks side by side (hence: 16x8 each) #define C8DC8 (4 * 16 * BPS) #define C8TM8 (4 * 16 * BPS + 8 * BPS) #define C8VE8 (5 * 16 * BPS) #define C8HE8 (5 * 16 * BPS + 8 * BPS) // intra 4x4 #define I4DC4 (6 * 16 * BPS + 0) #define I4TM4 (6 * 16 * BPS + 4) #define I4VE4 (6 * 16 * BPS + 8) #define I4HE4 (6 * 16 * BPS + 12) #define I4RD4 (6 * 16 * BPS + 4 * BPS + 0) #define I4VR4 (6 * 16 * BPS + 4 * BPS + 4) #define I4LD4 (6 * 16 * BPS + 4 * BPS + 8) #define I4VL4 (6 * 16 * BPS + 4 * BPS + 12) #define I4HD4 (6 * 16 * BPS + 8 * BPS + 0) #define I4HU4 (6 * 16 * BPS + 8 * BPS + 4) #define I4TMP (6 * 16 * BPS + 8 * BPS + 8) typedef int64_t score_t; // type used for scores, rate, distortion #define MAX_COST ((score_t)0x7fffffffffffffLL) #define QFIX 17 #define BIAS(b) ((b) << (QFIX - 8)) // Fun fact: this is the _only_ line where we're actually being lossy and // discarding bits. static WEBP_INLINE int QUANTDIV(int n, int iQ, int B) { return (n * iQ + B) >> QFIX; } // size of histogram used by CollectHistogram. #define MAX_COEFF_THRESH 31 typedef struct VP8Histogram VP8Histogram; struct VP8Histogram { // TODO(skal): we only need to store the max_value and last_non_zero actually. int distribution[MAX_COEFF_THRESH + 1]; }; // Uncomment the following to remove token-buffer code: // #define DISABLE_TOKEN_BUFFER //------------------------------------------------------------------------------ // Headers typedef uint32_t proba_t; // 16b + 16b typedef uint8_t ProbaArray[NUM_CTX][NUM_PROBAS]; typedef proba_t StatsArray[NUM_CTX][NUM_PROBAS]; typedef uint16_t CostArray[NUM_CTX][MAX_VARIABLE_LEVEL + 1]; typedef double LFStats[NUM_MB_SEGMENTS][MAX_LF_LEVELS]; // filter stats typedef struct VP8Encoder VP8Encoder; // segment features typedef struct { int num_segments_; // Actual number of segments. 1 segment only = unused. int update_map_; // whether to update the segment map or not. // must be 0 if there's only 1 segment. int size_; // bit-cost for transmitting the segment map } VP8SegmentHeader; // Struct collecting all frame-persistent probabilities. typedef struct { uint8_t segments_[3]; // probabilities for segment tree uint8_t skip_proba_; // final probability of being skipped. ProbaArray coeffs_[NUM_TYPES][NUM_BANDS]; // 924 bytes StatsArray stats_[NUM_TYPES][NUM_BANDS]; // 4224 bytes CostArray level_cost_[NUM_TYPES][NUM_BANDS]; // 11.4k int dirty_; // if true, need to call VP8CalculateLevelCosts() int use_skip_proba_; // Note: we always use skip_proba for now. int nb_skip_; // number of skipped blocks } VP8Proba; // Filter parameters. Not actually used in the code (we don't perform // the in-loop filtering), but filled from user's config typedef struct { int simple_; // filtering type: 0=complex, 1=simple int level_; // base filter level [0..63] int sharpness_; // [0..7] int i4x4_lf_delta_; // delta filter level for i4x4 relative to i16x16 } VP8FilterHeader; //------------------------------------------------------------------------------ // Informations about the macroblocks. typedef struct { // block type unsigned int type_:2; // 0=i4x4, 1=i16x16 unsigned int uv_mode_:2; unsigned int skip_:1; unsigned int segment_:2; uint8_t alpha_; // quantization-susceptibility } VP8MBInfo; typedef struct VP8Matrix { uint16_t q_[16]; // quantizer steps uint16_t iq_[16]; // reciprocals, fixed point. uint16_t bias_[16]; // rounding bias uint16_t zthresh_[16]; // value under which a coefficient is zeroed uint16_t sharpen_[16]; // frequency boosters for slight sharpening } VP8Matrix; typedef struct { VP8Matrix y1_, y2_, uv_; // quantization matrices int alpha_; // quant-susceptibility, range [-127,127]. Zero is neutral. // Lower values indicate a lower risk of blurriness. int beta_; // filter-susceptibility, range [0,255]. int quant_; // final segment quantizer. int fstrength_; // final in-loop filtering strength int max_edge_; // max edge delta (for filtering strength) int min_disto_; // minimum distortion required to trigger filtering record // reactivities int lambda_i16_, lambda_i4_, lambda_uv_; int lambda_mode_, lambda_trellis_, tlambda_; int lambda_trellis_i16_, lambda_trellis_i4_, lambda_trellis_uv_; } VP8SegmentInfo; // Handy transient struct to accumulate score and info during RD-optimization // and mode evaluation. typedef struct { score_t D, SD; // Distortion, spectral distortion score_t H, R, score; // header bits, rate, score. int16_t y_dc_levels[16]; // Quantized levels for luma-DC, luma-AC, chroma. int16_t y_ac_levels[16][16]; int16_t uv_levels[4 + 4][16]; int mode_i16; // mode number for intra16 prediction uint8_t modes_i4[16]; // mode numbers for intra4 predictions int mode_uv; // mode number of chroma prediction uint32_t nz; // non-zero blocks } VP8ModeScore; // Iterator structure to iterate through macroblocks, pointing to the // right neighbouring data (samples, predictions, contexts, ...) typedef struct { int x_, y_; // current macroblock int y_stride_, uv_stride_; // respective strides uint8_t* yuv_in_; // input samples uint8_t* yuv_out_; // output samples uint8_t* yuv_out2_; // secondary buffer swapped with yuv_out_. uint8_t* yuv_p_; // scratch buffer for prediction VP8Encoder* enc_; // back-pointer VP8MBInfo* mb_; // current macroblock VP8BitWriter* bw_; // current bit-writer uint8_t* preds_; // intra mode predictors (4x4 blocks) uint32_t* nz_; // non-zero pattern uint8_t i4_boundary_[37]; // 32+5 boundary samples needed by intra4x4 uint8_t* i4_top_; // pointer to the current top boundary sample int i4_; // current intra4x4 mode being tested int top_nz_[9]; // top-non-zero context. int left_nz_[9]; // left-non-zero. left_nz[8] is independent. uint64_t bit_count_[4][3]; // bit counters for coded levels. uint64_t luma_bits_; // macroblock bit-cost for luma uint64_t uv_bits_; // macroblock bit-cost for chroma LFStats* lf_stats_; // filter stats (borrowed from enc_) int do_trellis_; // if true, perform extra level optimisation int count_down_; // number of mb still to be processed int count_down0_; // starting counter value (for progress) int percent0_; // saved initial progress percent uint8_t* y_left_; // left luma samples (addressable from index -1 to 15). uint8_t* u_left_; // left u samples (addressable from index -1 to 7) uint8_t* v_left_; // left v samples (addressable from index -1 to 7) uint8_t* y_top_; // top luma samples at position 'x_' uint8_t* uv_top_; // top u/v samples at position 'x_', packed as 16 bytes // memory for storing y/u/v_left_ and yuv_in_/out_* uint8_t yuv_left_mem_[17 + 16 + 16 + 8 + ALIGN_CST]; // memory for *_left_ uint8_t yuv_mem_[3 * YUV_SIZE + PRED_SIZE + ALIGN_CST]; // memory for yuv_* } VP8EncIterator; // in iterator.c // must be called first void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it); // restart a scan void VP8IteratorReset(VP8EncIterator* const it); // reset iterator position to row 'y' void VP8IteratorSetRow(VP8EncIterator* const it, int y); // set count down (=number of iterations to go) void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down); // return true if iteration is finished int VP8IteratorIsDone(const VP8EncIterator* const it); // Import uncompressed samples from source. // If tmp_32 is not NULL, import boundary samples too. // tmp_32 is a 32-bytes scratch buffer that must be aligned in memory. void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32); // export decimated samples void VP8IteratorExport(const VP8EncIterator* const it); // go to next macroblock. Returns false if not finished. int VP8IteratorNext(VP8EncIterator* const it); // save the yuv_out_ boundary values to top_/left_ arrays for next iterations. void VP8IteratorSaveBoundary(VP8EncIterator* const it); // Report progression based on macroblock rows. Return 0 for user-abort request. int VP8IteratorProgress(const VP8EncIterator* const it, int final_delta_percent); // Intra4x4 iterations void VP8IteratorStartI4(VP8EncIterator* const it); // returns true if not done. int VP8IteratorRotateI4(VP8EncIterator* const it, const uint8_t* const yuv_out); // Non-zero context setup/teardown void VP8IteratorNzToBytes(VP8EncIterator* const it); void VP8IteratorBytesToNz(VP8EncIterator* const it); // Helper functions to set mode properties void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode); void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes); void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode); void VP8SetSkip(const VP8EncIterator* const it, int skip); void VP8SetSegment(const VP8EncIterator* const it, int segment); //------------------------------------------------------------------------------ // Paginated token buffer typedef struct VP8Tokens VP8Tokens; // struct details in token.c typedef struct { #if !defined(DISABLE_TOKEN_BUFFER) VP8Tokens* pages_; // first page VP8Tokens** last_page_; // last page uint16_t* tokens_; // set to (*last_page_)->tokens_ int left_; // how many free tokens left before the page is full. #endif int error_; // true in case of malloc error } VP8TBuffer; void VP8TBufferInit(VP8TBuffer* const b); // initialize an empty buffer void VP8TBufferClear(VP8TBuffer* const b); // de-allocate pages memory #if !defined(DISABLE_TOKEN_BUFFER) // Finalizes bitstream when probabilities are known. // Deletes the allocated token memory if final_pass is true. int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw, const uint8_t* const probas, int final_pass); // record the coding of coefficients without knowing the probabilities yet int VP8RecordCoeffTokens(int ctx, int coeff_type, int first, int last, const int16_t* const coeffs, VP8TBuffer* const tokens); // Estimate the final coded size given a set of 'probas'. size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas); // unused for now void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats); #endif // !DISABLE_TOKEN_BUFFER //------------------------------------------------------------------------------ // VP8Encoder struct VP8Encoder { const WebPConfig* config_; // user configuration and parameters WebPPicture* pic_; // input / output picture // headers VP8FilterHeader filter_hdr_; // filtering information VP8SegmentHeader segment_hdr_; // segment information int profile_; // VP8's profile, deduced from Config. // dimension, in macroblock units. int mb_w_, mb_h_; int preds_w_; // stride of the *preds_ prediction plane (=4*mb_w + 1) // number of partitions (1, 2, 4 or 8 = MAX_NUM_PARTITIONS) int num_parts_; // per-partition boolean decoders. VP8BitWriter bw_; // part0 VP8BitWriter parts_[MAX_NUM_PARTITIONS]; // token partitions VP8TBuffer tokens_; // token buffer int percent_; // for progress // transparency blob int has_alpha_; uint8_t* alpha_data_; // non-NULL if transparency is present uint32_t alpha_data_size_; WebPWorker alpha_worker_; // enhancement layer int use_layer_; VP8BitWriter layer_bw_; uint8_t* layer_data_; size_t layer_data_size_; // quantization info (one set of DC/AC dequant factor per segment) VP8SegmentInfo dqm_[NUM_MB_SEGMENTS]; int base_quant_; // nominal quantizer value. Only used // for relative coding of segments' quant. int alpha_; // global susceptibility (<=> complexity) int uv_alpha_; // U/V quantization susceptibility // global offset of quantizers, shared by all segments int dq_y1_dc_; int dq_y2_dc_, dq_y2_ac_; int dq_uv_dc_, dq_uv_ac_; // probabilities and statistics VP8Proba proba_; uint64_t sse_[4]; // sum of Y/U/V/A squared errors for all macroblocks uint64_t sse_count_; // pixel count for the sse_[] stats int coded_size_; int residual_bytes_[3][4]; int block_count_[3]; // quality/speed settings int method_; // 0=fastest, 6=best/slowest. VP8RDLevel rd_opt_level_; // Deduced from method_. int max_i4_header_bits_; // partition #0 safeness factor int thread_level_; // derived from config->thread_level int do_search_; // derived from config->target_XXX int use_tokens_; // if true, use token buffer // Memory VP8MBInfo* mb_info_; // contextual macroblock infos (mb_w_ + 1) uint8_t* preds_; // predictions modes: (4*mb_w+1) * (4*mb_h+1) uint32_t* nz_; // non-zero bit context: mb_w+1 uint8_t *y_top_; // top luma samples. uint8_t *uv_top_; // top u/v samples. // U and V are packed into 16 bytes (8 U + 8 V) LFStats *lf_stats_; // autofilter stats (if NULL, autofilter is off) }; //------------------------------------------------------------------------------ // internal functions. Not public. // in tree.c extern const uint8_t VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS]; extern const uint8_t VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS]; // Reset the token probabilities to their initial (default) values void VP8DefaultProbas(VP8Encoder* const enc); // Write the token probabilities void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas); // Writes the partition #0 modes (that is: all intra modes) void VP8CodeIntraModes(VP8Encoder* const enc); // in syntax.c // Generates the final bitstream by coding the partition0 and headers, // and appending an assembly of all the pre-coded token partitions. // Return true if everything is ok. int VP8EncWrite(VP8Encoder* const enc); // Release memory allocated for bit-writing in VP8EncLoop & seq. void VP8EncFreeBitWriters(VP8Encoder* const enc); // in frame.c extern const uint8_t VP8EncBands[16 + 1]; extern const uint8_t VP8Cat3[]; extern const uint8_t VP8Cat4[]; extern const uint8_t VP8Cat5[]; extern const uint8_t VP8Cat6[]; // Form all the four Intra16x16 predictions in the yuv_p_ cache void VP8MakeLuma16Preds(const VP8EncIterator* const it); // Form all the four Chroma8x8 predictions in the yuv_p_ cache void VP8MakeChroma8Preds(const VP8EncIterator* const it); // Form all the ten Intra4x4 predictions in the yuv_p_ cache // for the 4x4 block it->i4_ void VP8MakeIntra4Preds(const VP8EncIterator* const it); // Rate calculation int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd); int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]); int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd); // Main coding calls int VP8EncLoop(VP8Encoder* const enc); int VP8EncTokenLoop(VP8Encoder* const enc); // in webpenc.c // Assign an error code to a picture. Return false for convenience. int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error); int WebPReportProgress(const WebPPicture* const pic, int percent, int* const percent_store); // in analysis.c // Main analysis loop. Decides the segmentations and complexity. // Assigns a first guess for Intra16 and uvmode_ prediction modes. int VP8EncAnalyze(VP8Encoder* const enc); // in quant.c // Sets up segment's quantization values, base_quant_ and filter strengths. void VP8SetSegmentParams(VP8Encoder* const enc, float quality); // Pick best modes and fills the levels. Returns true if skipped. int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, VP8RDLevel rd_opt); // in alpha.c void VP8EncInitAlpha(VP8Encoder* const enc); // initialize alpha compression int VP8EncStartAlpha(VP8Encoder* const enc); // start alpha coding process int VP8EncFinishAlpha(VP8Encoder* const enc); // finalize compressed data int VP8EncDeleteAlpha(VP8Encoder* const enc); // delete compressed data // in layer.c void VP8EncInitLayer(VP8Encoder* const enc); // init everything void VP8EncCodeLayerBlock(VP8EncIterator* it); // code one more macroblock int VP8EncFinishLayer(VP8Encoder* const enc); // finalize coding void VP8EncDeleteLayer(VP8Encoder* enc); // reclaim memory // in filter.c // SSIM utils typedef struct { double w, xm, ym, xxm, xym, yym; } DistoStats; void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst); void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1, const uint8_t* src2, int stride2, int W, int H, DistoStats* const stats); double VP8SSIMGet(const DistoStats* const stats); double VP8SSIMGetSquaredError(const DistoStats* const stats); // autofilter void VP8InitFilter(VP8EncIterator* const it); void VP8StoreFilterStats(VP8EncIterator* const it); void VP8AdjustFilterStrength(VP8EncIterator* const it); // returns the approximate filtering strength needed to smooth a edge // step of 'delta', given a sharpness parameter 'sharpness'. int VP8FilterStrengthFromDelta(int sharpness, int delta); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_ENC_VP8ENCI_H_ */ libwebp-0.4.0/src/enc/webpenc.c0000644000014400001440000003306212255002107013170 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // WebP encoder: main entry point // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #include #include "./vp8enci.h" #include "./vp8li.h" #include "../utils/utils.h" // #define PRINT_MEMORY_INFO #ifdef PRINT_MEMORY_INFO #include #endif //------------------------------------------------------------------------------ int WebPGetEncoderVersion(void) { return (ENC_MAJ_VERSION << 16) | (ENC_MIN_VERSION << 8) | ENC_REV_VERSION; } //------------------------------------------------------------------------------ // WebPPicture //------------------------------------------------------------------------------ static int DummyWriter(const uint8_t* data, size_t data_size, const WebPPicture* const picture) { // The following are to prevent 'unused variable' error message. (void)data; (void)data_size; (void)picture; return 1; } int WebPPictureInitInternal(WebPPicture* picture, int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) { return 0; // caller/system version mismatch! } if (picture != NULL) { memset(picture, 0, sizeof(*picture)); picture->writer = DummyWriter; WebPEncodingSetError(picture, VP8_ENC_OK); } return 1; } //------------------------------------------------------------------------------ // VP8Encoder //------------------------------------------------------------------------------ static void ResetSegmentHeader(VP8Encoder* const enc) { VP8SegmentHeader* const hdr = &enc->segment_hdr_; hdr->num_segments_ = enc->config_->segments; hdr->update_map_ = (hdr->num_segments_ > 1); hdr->size_ = 0; } static void ResetFilterHeader(VP8Encoder* const enc) { VP8FilterHeader* const hdr = &enc->filter_hdr_; hdr->simple_ = 1; hdr->level_ = 0; hdr->sharpness_ = 0; hdr->i4x4_lf_delta_ = 0; } static void ResetBoundaryPredictions(VP8Encoder* const enc) { // init boundary values once for all // Note: actually, initializing the preds_[] is only needed for intra4. int i; uint8_t* const top = enc->preds_ - enc->preds_w_; uint8_t* const left = enc->preds_ - 1; for (i = -1; i < 4 * enc->mb_w_; ++i) { top[i] = B_DC_PRED; } for (i = 0; i < 4 * enc->mb_h_; ++i) { left[i * enc->preds_w_] = B_DC_PRED; } enc->nz_[-1] = 0; // constant } // Mapping from config->method_ to coding tools used. //-------------------+---+---+---+---+---+---+---+ // Method | 0 | 1 | 2 | 3 |(4)| 5 | 6 | //-------------------+---+---+---+---+---+---+---+ // fast probe | x | | | x | | | | //-------------------+---+---+---+---+---+---+---+ // dynamic proba | ~ | x | x | x | x | x | x | //-------------------+---+---+---+---+---+---+---+ // fast mode analysis| | | | | x | x | x | //-------------------+---+---+---+---+---+---+---+ // basic rd-opt | | | | x | x | x | x | //-------------------+---+---+---+---+---+---+---+ // disto-score i4/16 | | | x | | | | | //-------------------+---+---+---+---+---+---+---+ // rd-opt i4/16 | | | ~ | x | x | x | x | //-------------------+---+---+---+---+---+---+---+ // token buffer (opt)| | | | x | x | x | x | //-------------------+---+---+---+---+---+---+---+ // Trellis | | | | | | x |Ful| //-------------------+---+---+---+---+---+---+---+ // full-SNS | | | | | x | x | x | //-------------------+---+---+---+---+---+---+---+ static void MapConfigToTools(VP8Encoder* const enc) { const WebPConfig* const config = enc->config_; const int method = config->method; const int limit = 100 - config->partition_limit; enc->method_ = method; enc->rd_opt_level_ = (method >= 6) ? RD_OPT_TRELLIS_ALL : (method >= 5) ? RD_OPT_TRELLIS : (method >= 3) ? RD_OPT_BASIC : RD_OPT_NONE; enc->max_i4_header_bits_ = 256 * 16 * 16 * // upper bound: up to 16bit per 4x4 block (limit * limit) / (100 * 100); // ... modulated with a quadratic curve. enc->thread_level_ = config->thread_level; enc->do_search_ = (config->target_size > 0 || config->target_PSNR > 0); if (!config->low_memory) { #if !defined(DISABLE_TOKEN_BUFFER) enc->use_tokens_ = (enc->rd_opt_level_ >= RD_OPT_BASIC); // need rd stats #endif if (enc->use_tokens_) { enc->num_parts_ = 1; // doesn't work with multi-partition } } } // Memory scaling with dimensions: // memory (bytes) ~= 2.25 * w + 0.0625 * w * h // // Typical memory footprint (768x510 picture) // Memory used: // encoder: 33919 // block cache: 2880 // info: 3072 // preds: 24897 // top samples: 1623 // non-zero: 196 // lf-stats: 2048 // total: 68635 // Transient object sizes: // VP8EncIterator: 352 // VP8ModeScore: 912 // VP8SegmentInfo: 532 // VP8Proba: 31032 // LFStats: 2048 // Picture size (yuv): 589824 static VP8Encoder* InitVP8Encoder(const WebPConfig* const config, WebPPicture* const picture) { const int use_filter = (config->filter_strength > 0) || (config->autofilter > 0); const int mb_w = (picture->width + 15) >> 4; const int mb_h = (picture->height + 15) >> 4; const int preds_w = 4 * mb_w + 1; const int preds_h = 4 * mb_h + 1; const size_t preds_size = preds_w * preds_h * sizeof(uint8_t); const int top_stride = mb_w * 16; const size_t nz_size = (mb_w + 1) * sizeof(uint32_t) + ALIGN_CST; const size_t info_size = mb_w * mb_h * sizeof(VP8MBInfo); const size_t samples_size = 2 * top_stride * sizeof(uint8_t) // top-luma/u/v + ALIGN_CST; // align all const size_t lf_stats_size = config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0; VP8Encoder* enc; uint8_t* mem; const uint64_t size = (uint64_t)sizeof(VP8Encoder) // main struct + ALIGN_CST // cache alignment + info_size // modes info + preds_size // prediction modes + samples_size // top/left samples + nz_size // coeff context bits + lf_stats_size; // autofilter stats #ifdef PRINT_MEMORY_INFO printf("===================================\n"); printf("Memory used:\n" " encoder: %ld\n" " info: %ld\n" " preds: %ld\n" " top samples: %ld\n" " non-zero: %ld\n" " lf-stats: %ld\n" " total: %ld\n", sizeof(VP8Encoder) + ALIGN_CST, info_size, preds_size, samples_size, nz_size, lf_stats_size, size); printf("Transient object sizes:\n" " VP8EncIterator: %ld\n" " VP8ModeScore: %ld\n" " VP8SegmentInfo: %ld\n" " VP8Proba: %ld\n" " LFStats: %ld\n", sizeof(VP8EncIterator), sizeof(VP8ModeScore), sizeof(VP8SegmentInfo), sizeof(VP8Proba), sizeof(LFStats)); printf("Picture size (yuv): %ld\n", mb_w * mb_h * 384 * sizeof(uint8_t)); printf("===================================\n"); #endif mem = (uint8_t*)WebPSafeMalloc(size, sizeof(*mem)); if (mem == NULL) { WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); return NULL; } enc = (VP8Encoder*)mem; mem = (uint8_t*)DO_ALIGN(mem + sizeof(*enc)); memset(enc, 0, sizeof(*enc)); enc->num_parts_ = 1 << config->partitions; enc->mb_w_ = mb_w; enc->mb_h_ = mb_h; enc->preds_w_ = preds_w; enc->mb_info_ = (VP8MBInfo*)mem; mem += info_size; enc->preds_ = ((uint8_t*)mem) + 1 + enc->preds_w_; mem += preds_w * preds_h * sizeof(uint8_t); enc->nz_ = 1 + (uint32_t*)DO_ALIGN(mem); mem += nz_size; enc->lf_stats_ = lf_stats_size ? (LFStats*)DO_ALIGN(mem) : NULL; mem += lf_stats_size; // top samples (all 16-aligned) mem = (uint8_t*)DO_ALIGN(mem); enc->y_top_ = (uint8_t*)mem; enc->uv_top_ = enc->y_top_ + top_stride; mem += 2 * top_stride; assert(mem <= (uint8_t*)enc + size); enc->config_ = config; enc->profile_ = use_filter ? ((config->filter_type == 1) ? 0 : 1) : 2; enc->pic_ = picture; enc->percent_ = 0; MapConfigToTools(enc); VP8EncDspInit(); VP8DefaultProbas(enc); ResetSegmentHeader(enc); ResetFilterHeader(enc); ResetBoundaryPredictions(enc); VP8EncInitAlpha(enc); #ifdef WEBP_EXPERIMENTAL_FEATURES VP8EncInitLayer(enc); #endif VP8TBufferInit(&enc->tokens_); return enc; } static int DeleteVP8Encoder(VP8Encoder* enc) { int ok = 1; if (enc != NULL) { ok = VP8EncDeleteAlpha(enc); #ifdef WEBP_EXPERIMENTAL_FEATURES VP8EncDeleteLayer(enc); #endif VP8TBufferClear(&enc->tokens_); free(enc); } return ok; } //------------------------------------------------------------------------------ static double GetPSNR(uint64_t err, uint64_t size) { return (err > 0 && size > 0) ? 10. * log10(255. * 255. * size / err) : 99.; } static void FinalizePSNR(const VP8Encoder* const enc) { WebPAuxStats* stats = enc->pic_->stats; const uint64_t size = enc->sse_count_; const uint64_t* const sse = enc->sse_; stats->PSNR[0] = (float)GetPSNR(sse[0], size); stats->PSNR[1] = (float)GetPSNR(sse[1], size / 4); stats->PSNR[2] = (float)GetPSNR(sse[2], size / 4); stats->PSNR[3] = (float)GetPSNR(sse[0] + sse[1] + sse[2], size * 3 / 2); stats->PSNR[4] = (float)GetPSNR(sse[3], size); } static void StoreStats(VP8Encoder* const enc) { WebPAuxStats* const stats = enc->pic_->stats; if (stats != NULL) { int i, s; for (i = 0; i < NUM_MB_SEGMENTS; ++i) { stats->segment_level[i] = enc->dqm_[i].fstrength_; stats->segment_quant[i] = enc->dqm_[i].quant_; for (s = 0; s <= 2; ++s) { stats->residual_bytes[s][i] = enc->residual_bytes_[s][i]; } } FinalizePSNR(enc); stats->coded_size = enc->coded_size_; for (i = 0; i < 3; ++i) { stats->block_count[i] = enc->block_count_[i]; } } WebPReportProgress(enc->pic_, 100, &enc->percent_); // done! } int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error) { assert((int)error < VP8_ENC_ERROR_LAST); assert((int)error >= VP8_ENC_OK); ((WebPPicture*)pic)->error_code = error; return 0; } int WebPReportProgress(const WebPPicture* const pic, int percent, int* const percent_store) { if (percent_store != NULL && percent != *percent_store) { *percent_store = percent; if (pic->progress_hook && !pic->progress_hook(percent, pic)) { // user abort requested WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT); return 0; } } return 1; // ok } //------------------------------------------------------------------------------ int WebPEncode(const WebPConfig* config, WebPPicture* pic) { int ok = 0; if (pic == NULL) return 0; WebPEncodingSetError(pic, VP8_ENC_OK); // all ok so far if (config == NULL) // bad params return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER); if (!WebPValidateConfig(config)) return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION); if (pic->width <= 0 || pic->height <= 0) return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION); if (pic->width > WEBP_MAX_DIMENSION || pic->height > WEBP_MAX_DIMENSION) return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION); if (pic->stats != NULL) memset(pic->stats, 0, sizeof(*pic->stats)); if (!config->lossless) { VP8Encoder* enc = NULL; if (pic->y == NULL || pic->u == NULL || pic->v == NULL) { // Make sure we have YUVA samples. float dithering = 0.f; if (config->preprocessing & 2) { const float x = config->quality / 100.f; const float x2 = x * x; // slowly decreasing from max dithering at low quality (q->0) // to 0.5 dithering amplitude at high quality (q->100) dithering = 1.0f + (0.5f - 1.0f) * x2 * x2; } if (!WebPPictureARGBToYUVADithered(pic, WEBP_YUV420, dithering)) { return 0; } } enc = InitVP8Encoder(config, pic); if (enc == NULL) return 0; // pic->error is already set. // Note: each of the tasks below account for 20% in the progress report. ok = VP8EncAnalyze(enc); // Analysis is done, proceed to actual coding. ok = ok && VP8EncStartAlpha(enc); // possibly done in parallel if (!enc->use_tokens_) { ok = ok && VP8EncLoop(enc); } else { ok = ok && VP8EncTokenLoop(enc); } ok = ok && VP8EncFinishAlpha(enc); #ifdef WEBP_EXPERIMENTAL_FEATURES ok = ok && VP8EncFinishLayer(enc); #endif ok = ok && VP8EncWrite(enc); StoreStats(enc); if (!ok) { VP8EncFreeBitWriters(enc); } ok &= DeleteVP8Encoder(enc); // must always be called, even if !ok } else { // Make sure we have ARGB samples. if (pic->argb == NULL && !WebPPictureYUVAToARGB(pic)) { return 0; } ok = VP8LEncodeImage(config, pic); // Sets pic->error in case of problem. } return ok; } libwebp-0.4.0/src/enc/backward_references.c0000644000014400001440000007304312255002107015527 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) // #include #include #include #include "./backward_references.h" #include "./histogram.h" #include "../dsp/lossless.h" #include "../utils/color_cache.h" #include "../utils/utils.h" #define VALUES_IN_BYTE 256 #define HASH_BITS 18 #define HASH_SIZE (1 << HASH_BITS) #define HASH_MULTIPLIER (0xc6a4a7935bd1e995ULL) // 1M window (4M bytes) minus 120 special codes for short distances. #define WINDOW_SIZE ((1 << 20) - 120) // Bounds for the match length. #define MIN_LENGTH 2 #define MAX_LENGTH 4096 typedef struct { // Stores the most recently added position with the given hash value. int32_t hash_to_first_index_[HASH_SIZE]; // chain_[pos] stores the previous position with the same hash value // for every pixel in the image. int32_t* chain_; } HashChain; // ----------------------------------------------------------------------------- static const uint8_t plane_to_code_lut[128] = { 96, 73, 55, 39, 23, 13, 5, 1, 255, 255, 255, 255, 255, 255, 255, 255, 101, 78, 58, 42, 26, 16, 8, 2, 0, 3, 9, 17, 27, 43, 59, 79, 102, 86, 62, 46, 32, 20, 10, 6, 4, 7, 11, 21, 33, 47, 63, 87, 105, 90, 70, 52, 37, 28, 18, 14, 12, 15, 19, 29, 38, 53, 71, 91, 110, 99, 82, 66, 48, 35, 30, 24, 22, 25, 31, 36, 49, 67, 83, 100, 115, 108, 94, 76, 64, 50, 44, 40, 34, 41, 45, 51, 65, 77, 95, 109, 118, 113, 103, 92, 80, 68, 60, 56, 54, 57, 61, 69, 81, 93, 104, 114, 119, 116, 111, 106, 97, 88, 84, 74, 72, 75, 85, 89, 98, 107, 112, 117 }; static int DistanceToPlaneCode(int xsize, int dist) { const int yoffset = dist / xsize; const int xoffset = dist - yoffset * xsize; if (xoffset <= 8 && yoffset < 8) { return plane_to_code_lut[yoffset * 16 + 8 - xoffset] + 1; } else if (xoffset > xsize - 8 && yoffset < 7) { return plane_to_code_lut[(yoffset + 1) * 16 + 8 + (xsize - xoffset)] + 1; } return dist + 120; } static WEBP_INLINE int FindMatchLength(const uint32_t* const array1, const uint32_t* const array2, const int max_limit) { int match_len = 0; while (match_len < max_limit && array1[match_len] == array2[match_len]) { ++match_len; } return match_len; } // ----------------------------------------------------------------------------- // VP8LBackwardRefs void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs) { if (refs != NULL) { refs->refs = NULL; refs->size = 0; refs->max_size = 0; } } void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs) { if (refs != NULL) { free(refs->refs); VP8LInitBackwardRefs(refs); } } int VP8LBackwardRefsAlloc(VP8LBackwardRefs* const refs, int max_size) { assert(refs != NULL); refs->size = 0; refs->max_size = 0; refs->refs = (PixOrCopy*)WebPSafeMalloc((uint64_t)max_size, sizeof(*refs->refs)); if (refs->refs == NULL) return 0; refs->max_size = max_size; return 1; } // ----------------------------------------------------------------------------- // Hash chains static WEBP_INLINE uint64_t GetPixPairHash64(const uint32_t* const argb) { uint64_t key = ((uint64_t)(argb[1]) << 32) | argb[0]; key = (key * HASH_MULTIPLIER) >> (64 - HASH_BITS); return key; } static int HashChainInit(HashChain* const p, int size) { int i; p->chain_ = (int*)WebPSafeMalloc((uint64_t)size, sizeof(*p->chain_)); if (p->chain_ == NULL) { return 0; } for (i = 0; i < size; ++i) { p->chain_[i] = -1; } for (i = 0; i < HASH_SIZE; ++i) { p->hash_to_first_index_[i] = -1; } return 1; } static void HashChainDelete(HashChain* const p) { if (p != NULL) { free(p->chain_); free(p); } } // Insertion of two pixels at a time. static void HashChainInsert(HashChain* const p, const uint32_t* const argb, int pos) { const uint64_t hash_code = GetPixPairHash64(argb); p->chain_[pos] = p->hash_to_first_index_[hash_code]; p->hash_to_first_index_[hash_code] = pos; } static void GetParamsForHashChainFindCopy(int quality, int xsize, int cache_bits, int* window_size, int* iter_pos, int* iter_limit) { const int iter_mult = (quality < 27) ? 1 : 1 + ((quality - 27) >> 4); const int iter_neg = -iter_mult * (quality >> 1); // Limit the backward-ref window size for lower qualities. const int max_window_size = (quality > 50) ? WINDOW_SIZE : (quality > 25) ? (xsize << 8) : (xsize << 4); assert(xsize > 0); *window_size = (max_window_size > WINDOW_SIZE) ? WINDOW_SIZE : max_window_size; *iter_pos = 8 + (quality >> 3); // For lower entropy images, the rigorous search loop in HashChainFindCopy // can be relaxed. *iter_limit = (cache_bits > 0) ? iter_neg : iter_neg / 2; } static int HashChainFindCopy(const HashChain* const p, int base_position, int xsize_signed, const uint32_t* const argb, int max_len, int window_size, int iter_pos, int iter_limit, int* const distance_ptr, int* const length_ptr) { const uint32_t* const argb_start = argb + base_position; uint64_t best_val = 0; uint32_t best_length = 1; uint32_t best_distance = 0; const uint32_t xsize = (uint32_t)xsize_signed; const int min_pos = (base_position > window_size) ? base_position - window_size : 0; int pos; assert(xsize > 0); if (max_len > MAX_LENGTH) { max_len = MAX_LENGTH; } for (pos = p->hash_to_first_index_[GetPixPairHash64(argb_start)]; pos >= min_pos; pos = p->chain_[pos]) { uint64_t val; uint32_t curr_length; uint32_t distance; const uint64_t* const ptr1 = (const uint64_t*)(argb + pos + best_length - 1); const uint64_t* const ptr2 = (const uint64_t*)(argb_start + best_length - 1); if (iter_pos < 0) { if (iter_pos < iter_limit || best_val >= 0xff0000) { break; } } --iter_pos; // Before 'expensive' linear match, check if the two arrays match at the // current best length index and also for the succeeding elements. if (*ptr1 != *ptr2) continue; curr_length = FindMatchLength(argb + pos, argb_start, max_len); if (curr_length < best_length) continue; distance = (uint32_t)(base_position - pos); val = curr_length << 16; // Favoring 2d locality here gives savings for certain images. if (distance < 9 * xsize) { const uint32_t y = distance / xsize; uint32_t x = distance % xsize; if (x > (xsize >> 1)) { x = xsize - x; } if (x <= 7) { val += 9 * 9 + 9 * 9; val -= y * y + x * x; } } if (best_val < val) { best_val = val; best_length = curr_length; best_distance = distance; if (curr_length >= (uint32_t)max_len) { break; } if ((best_distance == 1 || distance == xsize) && best_length >= 128) { break; } } } *distance_ptr = (int)best_distance; *length_ptr = best_length; return (best_length >= MIN_LENGTH); } static WEBP_INLINE void PushBackCopy(VP8LBackwardRefs* const refs, int length) { int size = refs->size; while (length >= MAX_LENGTH) { refs->refs[size++] = PixOrCopyCreateCopy(1, MAX_LENGTH); length -= MAX_LENGTH; } if (length > 0) { refs->refs[size++] = PixOrCopyCreateCopy(1, length); } refs->size = size; } static void BackwardReferencesRle(int xsize, int ysize, const uint32_t* const argb, VP8LBackwardRefs* const refs) { const int pix_count = xsize * ysize; int match_len = 0; int i; refs->size = 0; PushBackCopy(refs, match_len); // i=0 case refs->refs[refs->size++] = PixOrCopyCreateLiteral(argb[0]); for (i = 1; i < pix_count; ++i) { if (argb[i] == argb[i - 1]) { ++match_len; } else { PushBackCopy(refs, match_len); match_len = 0; refs->refs[refs->size++] = PixOrCopyCreateLiteral(argb[i]); } } PushBackCopy(refs, match_len); } static int BackwardReferencesHashChain(int xsize, int ysize, const uint32_t* const argb, int cache_bits, int quality, VP8LBackwardRefs* const refs) { int i; int ok = 0; int cc_init = 0; const int use_color_cache = (cache_bits > 0); const int pix_count = xsize * ysize; HashChain* const hash_chain = (HashChain*)malloc(sizeof(*hash_chain)); VP8LColorCache hashers; int window_size = WINDOW_SIZE; int iter_pos = 1; int iter_limit = -1; if (hash_chain == NULL) return 0; if (use_color_cache) { cc_init = VP8LColorCacheInit(&hashers, cache_bits); if (!cc_init) goto Error; } if (!HashChainInit(hash_chain, pix_count)) goto Error; refs->size = 0; GetParamsForHashChainFindCopy(quality, xsize, cache_bits, &window_size, &iter_pos, &iter_limit); for (i = 0; i < pix_count; ) { // Alternative#1: Code the pixels starting at 'i' using backward reference. int offset = 0; int len = 0; if (i < pix_count - 1) { // FindCopy(i,..) reads pixels at [i] and [i + 1]. int max_len = pix_count - i; HashChainFindCopy(hash_chain, i, xsize, argb, max_len, window_size, iter_pos, iter_limit, &offset, &len); } if (len >= MIN_LENGTH) { // Alternative#2: Insert the pixel at 'i' as literal, and code the // pixels starting at 'i + 1' using backward reference. int offset2 = 0; int len2 = 0; int k; HashChainInsert(hash_chain, &argb[i], i); if (i < pix_count - 2) { // FindCopy(i+1,..) reads [i + 1] and [i + 2]. int max_len = pix_count - (i + 1); HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len, window_size, iter_pos, iter_limit, &offset2, &len2); if (len2 > len + 1) { const uint32_t pixel = argb[i]; // Alternative#2 is a better match. So push pixel at 'i' as literal. if (use_color_cache && VP8LColorCacheContains(&hashers, pixel)) { const int ix = VP8LColorCacheGetIndex(&hashers, pixel); refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix); } else { if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel); refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel); } ++refs->size; i++; // Backward reference to be done for next pixel. len = len2; offset = offset2; } } if (len >= MAX_LENGTH) { len = MAX_LENGTH - 1; } refs->refs[refs->size++] = PixOrCopyCreateCopy(offset, len); if (use_color_cache) { for (k = 0; k < len; ++k) { VP8LColorCacheInsert(&hashers, argb[i + k]); } } // Add to the hash_chain (but cannot add the last pixel). { const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i; for (k = 1; k < last; ++k) { HashChainInsert(hash_chain, &argb[i + k], i + k); } } i += len; } else { const uint32_t pixel = argb[i]; if (use_color_cache && VP8LColorCacheContains(&hashers, pixel)) { // push pixel as a PixOrCopyCreateCacheIdx pixel const int ix = VP8LColorCacheGetIndex(&hashers, pixel); refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix); } else { if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel); refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel); } ++refs->size; if (i + 1 < pix_count) { HashChainInsert(hash_chain, &argb[i], i); } ++i; } } ok = 1; Error: if (cc_init) VP8LColorCacheClear(&hashers); HashChainDelete(hash_chain); return ok; } // ----------------------------------------------------------------------------- typedef struct { double alpha_[VALUES_IN_BYTE]; double red_[VALUES_IN_BYTE]; double literal_[PIX_OR_COPY_CODES_MAX]; double blue_[VALUES_IN_BYTE]; double distance_[NUM_DISTANCE_CODES]; } CostModel; static int BackwardReferencesTraceBackwards( int xsize, int ysize, int recursive_cost_model, const uint32_t* const argb, int quality, int cache_bits, VP8LBackwardRefs* const refs); static void ConvertPopulationCountTableToBitEstimates( int num_symbols, const int population_counts[], double output[]) { int sum = 0; int nonzeros = 0; int i; for (i = 0; i < num_symbols; ++i) { sum += population_counts[i]; if (population_counts[i] > 0) { ++nonzeros; } } if (nonzeros <= 1) { memset(output, 0, num_symbols * sizeof(*output)); } else { const double logsum = VP8LFastLog2(sum); for (i = 0; i < num_symbols; ++i) { output[i] = logsum - VP8LFastLog2(population_counts[i]); } } } static int CostModelBuild(CostModel* const m, int xsize, int ysize, int recursion_level, const uint32_t* const argb, int quality, int cache_bits) { int ok = 0; VP8LHistogram histo; VP8LBackwardRefs refs; if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize)) goto Error; if (recursion_level > 0) { if (!BackwardReferencesTraceBackwards(xsize, ysize, recursion_level - 1, argb, quality, cache_bits, &refs)) { goto Error; } } else { if (!BackwardReferencesHashChain(xsize, ysize, argb, cache_bits, quality, &refs)) { goto Error; } } VP8LHistogramCreate(&histo, &refs, cache_bits); ConvertPopulationCountTableToBitEstimates( VP8LHistogramNumCodes(&histo), histo.literal_, m->literal_); ConvertPopulationCountTableToBitEstimates( VALUES_IN_BYTE, histo.red_, m->red_); ConvertPopulationCountTableToBitEstimates( VALUES_IN_BYTE, histo.blue_, m->blue_); ConvertPopulationCountTableToBitEstimates( VALUES_IN_BYTE, histo.alpha_, m->alpha_); ConvertPopulationCountTableToBitEstimates( NUM_DISTANCE_CODES, histo.distance_, m->distance_); ok = 1; Error: VP8LClearBackwardRefs(&refs); return ok; } static WEBP_INLINE double GetLiteralCost(const CostModel* const m, uint32_t v) { return m->alpha_[v >> 24] + m->red_[(v >> 16) & 0xff] + m->literal_[(v >> 8) & 0xff] + m->blue_[v & 0xff]; } static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) { const int literal_idx = VALUES_IN_BYTE + NUM_LENGTH_CODES + idx; return m->literal_[literal_idx]; } static WEBP_INLINE double GetLengthCost(const CostModel* const m, uint32_t length) { int code, extra_bits; VP8LPrefixEncodeBits(length, &code, &extra_bits); return m->literal_[VALUES_IN_BYTE + code] + extra_bits; } static WEBP_INLINE double GetDistanceCost(const CostModel* const m, uint32_t distance) { int code, extra_bits; VP8LPrefixEncodeBits(distance, &code, &extra_bits); return m->distance_[code] + extra_bits; } static int BackwardReferencesHashChainDistanceOnly( int xsize, int ysize, int recursive_cost_model, const uint32_t* const argb, int quality, int cache_bits, uint32_t* const dist_array) { int i; int ok = 0; int cc_init = 0; const int pix_count = xsize * ysize; const int use_color_cache = (cache_bits > 0); float* const cost = (float*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*cost)); CostModel* cost_model = (CostModel*)malloc(sizeof(*cost_model)); HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain)); VP8LColorCache hashers; const double mul0 = (recursive_cost_model != 0) ? 1.0 : 0.68; const double mul1 = (recursive_cost_model != 0) ? 1.0 : 0.82; const int min_distance_code = 2; // TODO(vikasa): tune as function of quality int window_size = WINDOW_SIZE; int iter_pos = 1; int iter_limit = -1; if (cost == NULL || cost_model == NULL || hash_chain == NULL) goto Error; if (!HashChainInit(hash_chain, pix_count)) goto Error; if (use_color_cache) { cc_init = VP8LColorCacheInit(&hashers, cache_bits); if (!cc_init) goto Error; } if (!CostModelBuild(cost_model, xsize, ysize, recursive_cost_model, argb, quality, cache_bits)) { goto Error; } for (i = 0; i < pix_count; ++i) cost[i] = 1e38f; // We loop one pixel at a time, but store all currently best points to // non-processed locations from this point. dist_array[0] = 0; GetParamsForHashChainFindCopy(quality, xsize, cache_bits, &window_size, &iter_pos, &iter_limit); for (i = 0; i < pix_count; ++i) { double prev_cost = 0.0; int shortmax; if (i > 0) { prev_cost = cost[i - 1]; } for (shortmax = 0; shortmax < 2; ++shortmax) { int offset = 0; int len = 0; if (i < pix_count - 1) { // FindCopy reads pixels at [i] and [i + 1]. int max_len = shortmax ? 2 : pix_count - i; HashChainFindCopy(hash_chain, i, xsize, argb, max_len, window_size, iter_pos, iter_limit, &offset, &len); } if (len >= MIN_LENGTH) { const int code = DistanceToPlaneCode(xsize, offset); const double distance_cost = prev_cost + GetDistanceCost(cost_model, code); int k; for (k = 1; k < len; ++k) { const double cost_val = distance_cost + GetLengthCost(cost_model, k); if (cost[i + k] > cost_val) { cost[i + k] = (float)cost_val; dist_array[i + k] = k + 1; } } // This if is for speedup only. It roughly doubles the speed, and // makes compression worse by .1 %. if (len >= 128 && code <= min_distance_code) { // Long copy for short distances, let's skip the middle // lookups for better copies. // 1) insert the hashes. if (use_color_cache) { for (k = 0; k < len; ++k) { VP8LColorCacheInsert(&hashers, argb[i + k]); } } // 2) Add to the hash_chain (but cannot add the last pixel) { const int last = (len + i < pix_count - 1) ? len + i : pix_count - 1; for (k = i; k < last; ++k) { HashChainInsert(hash_chain, &argb[k], k); } } // 3) jump. i += len - 1; // for loop does ++i, thus -1 here. goto next_symbol; } } } if (i < pix_count - 1) { HashChainInsert(hash_chain, &argb[i], i); } { // inserting a literal pixel double cost_val = prev_cost; if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) { const int ix = VP8LColorCacheGetIndex(&hashers, argb[i]); cost_val += GetCacheCost(cost_model, ix) * mul0; } else { if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]); cost_val += GetLiteralCost(cost_model, argb[i]) * mul1; } if (cost[i] > cost_val) { cost[i] = (float)cost_val; dist_array[i] = 1; // only one is inserted. } } next_symbol: ; } // Last pixel still to do, it can only be a single step if not reached // through cheaper means already. ok = 1; Error: if (cc_init) VP8LColorCacheClear(&hashers); HashChainDelete(hash_chain); free(cost_model); free(cost); return ok; } // We pack the path at the end of *dist_array and return // a pointer to this part of the array. Example: // dist_array = [1x2xx3x2] => packed [1x2x1232], chosen_path = [1232] static void TraceBackwards(uint32_t* const dist_array, int dist_array_size, uint32_t** const chosen_path, int* const chosen_path_size) { uint32_t* path = dist_array + dist_array_size; uint32_t* cur = dist_array + dist_array_size - 1; while (cur >= dist_array) { const int k = *cur; --path; *path = k; cur -= k; } *chosen_path = path; *chosen_path_size = (int)(dist_array + dist_array_size - path); } static int BackwardReferencesHashChainFollowChosenPath( int xsize, int ysize, const uint32_t* const argb, int quality, int cache_bits, const uint32_t* const chosen_path, int chosen_path_size, VP8LBackwardRefs* const refs) { const int pix_count = xsize * ysize; const int use_color_cache = (cache_bits > 0); int size = 0; int i = 0; int k; int ix; int ok = 0; int cc_init = 0; int window_size = WINDOW_SIZE; int iter_pos = 1; int iter_limit = -1; HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain)); VP8LColorCache hashers; if (hash_chain == NULL || !HashChainInit(hash_chain, pix_count)) { goto Error; } if (use_color_cache) { cc_init = VP8LColorCacheInit(&hashers, cache_bits); if (!cc_init) goto Error; } refs->size = 0; GetParamsForHashChainFindCopy(quality, xsize, cache_bits, &window_size, &iter_pos, &iter_limit); for (ix = 0; ix < chosen_path_size; ++ix, ++size) { int offset = 0; int len = 0; int max_len = chosen_path[ix]; if (max_len != 1) { HashChainFindCopy(hash_chain, i, xsize, argb, max_len, window_size, iter_pos, iter_limit, &offset, &len); assert(len == max_len); refs->refs[size] = PixOrCopyCreateCopy(offset, len); if (use_color_cache) { for (k = 0; k < len; ++k) { VP8LColorCacheInsert(&hashers, argb[i + k]); } } { const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i; for (k = 0; k < last; ++k) { HashChainInsert(hash_chain, &argb[i + k], i + k); } } i += len; } else { if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) { // push pixel as a color cache index const int idx = VP8LColorCacheGetIndex(&hashers, argb[i]); refs->refs[size] = PixOrCopyCreateCacheIdx(idx); } else { if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]); refs->refs[size] = PixOrCopyCreateLiteral(argb[i]); } if (i + 1 < pix_count) { HashChainInsert(hash_chain, &argb[i], i); } ++i; } } assert(size <= refs->max_size); refs->size = size; ok = 1; Error: if (cc_init) VP8LColorCacheClear(&hashers); HashChainDelete(hash_chain); return ok; } // Returns 1 on success. static int BackwardReferencesTraceBackwards(int xsize, int ysize, int recursive_cost_model, const uint32_t* const argb, int quality, int cache_bits, VP8LBackwardRefs* const refs) { int ok = 0; const int dist_array_size = xsize * ysize; uint32_t* chosen_path = NULL; int chosen_path_size = 0; uint32_t* dist_array = (uint32_t*)WebPSafeMalloc((uint64_t)dist_array_size, sizeof(*dist_array)); if (dist_array == NULL) goto Error; if (!BackwardReferencesHashChainDistanceOnly( xsize, ysize, recursive_cost_model, argb, quality, cache_bits, dist_array)) { goto Error; } TraceBackwards(dist_array, dist_array_size, &chosen_path, &chosen_path_size); if (!BackwardReferencesHashChainFollowChosenPath( xsize, ysize, argb, quality, cache_bits, chosen_path, chosen_path_size, refs)) { goto Error; } ok = 1; Error: free(dist_array); return ok; } static void BackwardReferences2DLocality(int xsize, VP8LBackwardRefs* const refs) { int i; for (i = 0; i < refs->size; ++i) { if (PixOrCopyIsCopy(&refs->refs[i])) { const int dist = refs->refs[i].argb_or_distance; const int transformed_dist = DistanceToPlaneCode(xsize, dist); refs->refs[i].argb_or_distance = transformed_dist; } } } int VP8LGetBackwardReferences(int width, int height, const uint32_t* const argb, int quality, int cache_bits, int use_2d_locality, VP8LBackwardRefs* const best) { int ok = 0; int lz77_is_useful; VP8LBackwardRefs refs_rle, refs_lz77; const int num_pix = width * height; VP8LBackwardRefsAlloc(&refs_rle, num_pix); VP8LBackwardRefsAlloc(&refs_lz77, num_pix); VP8LInitBackwardRefs(best); if (refs_rle.refs == NULL || refs_lz77.refs == NULL) { Error1: VP8LClearBackwardRefs(&refs_rle); VP8LClearBackwardRefs(&refs_lz77); goto End; } if (!BackwardReferencesHashChain(width, height, argb, cache_bits, quality, &refs_lz77)) { goto End; } // Backward Reference using RLE only. BackwardReferencesRle(width, height, argb, &refs_rle); { double bit_cost_lz77, bit_cost_rle; VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo)); if (histo == NULL) goto Error1; // Evaluate lz77 coding VP8LHistogramCreate(histo, &refs_lz77, cache_bits); bit_cost_lz77 = VP8LHistogramEstimateBits(histo); // Evaluate RLE coding VP8LHistogramCreate(histo, &refs_rle, cache_bits); bit_cost_rle = VP8LHistogramEstimateBits(histo); // Decide if LZ77 is useful. lz77_is_useful = (bit_cost_lz77 < bit_cost_rle); free(histo); } // Choose appropriate backward reference. if (lz77_is_useful) { // TraceBackwards is costly. Don't execute it at lower quality. const int try_lz77_trace_backwards = (quality >= 25); *best = refs_lz77; // default guess: lz77 is better VP8LClearBackwardRefs(&refs_rle); if (try_lz77_trace_backwards) { // Set recursion level for large images using a color cache. const int recursion_level = (num_pix < 320 * 200) && (cache_bits > 0) ? 1 : 0; VP8LBackwardRefs refs_trace; if (!VP8LBackwardRefsAlloc(&refs_trace, num_pix)) { goto End; } if (BackwardReferencesTraceBackwards(width, height, recursion_level, argb, quality, cache_bits, &refs_trace)) { VP8LClearBackwardRefs(&refs_lz77); *best = refs_trace; } } } else { VP8LClearBackwardRefs(&refs_lz77); *best = refs_rle; } if (use_2d_locality) BackwardReferences2DLocality(width, best); ok = 1; End: if (!ok) { VP8LClearBackwardRefs(best); } return ok; } // Returns 1 on success. static int ComputeCacheHistogram(const uint32_t* const argb, int xsize, int ysize, const VP8LBackwardRefs* const refs, int cache_bits, VP8LHistogram* const histo) { int pixel_index = 0; int i; uint32_t k; VP8LColorCache hashers; const int use_color_cache = (cache_bits > 0); int cc_init = 0; if (use_color_cache) { cc_init = VP8LColorCacheInit(&hashers, cache_bits); if (!cc_init) return 0; } for (i = 0; i < refs->size; ++i) { const PixOrCopy* const v = &refs->refs[i]; if (PixOrCopyIsLiteral(v)) { if (use_color_cache && VP8LColorCacheContains(&hashers, argb[pixel_index])) { // push pixel as a cache index const int ix = VP8LColorCacheGetIndex(&hashers, argb[pixel_index]); const PixOrCopy token = PixOrCopyCreateCacheIdx(ix); VP8LHistogramAddSinglePixOrCopy(histo, &token); } else { VP8LHistogramAddSinglePixOrCopy(histo, v); } } else { VP8LHistogramAddSinglePixOrCopy(histo, v); } if (use_color_cache) { for (k = 0; k < PixOrCopyLength(v); ++k) { VP8LColorCacheInsert(&hashers, argb[pixel_index + k]); } } pixel_index += PixOrCopyLength(v); } assert(pixel_index == xsize * ysize); (void)xsize; // xsize is not used in non-debug compilations otherwise. (void)ysize; // ysize is not used in non-debug compilations otherwise. if (cc_init) VP8LColorCacheClear(&hashers); return 1; } // Returns how many bits are to be used for a color cache. int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb, int xsize, int ysize, int* const best_cache_bits) { int ok = 0; int cache_bits; double lowest_entropy = 1e99; VP8LBackwardRefs refs; static const double kSmallPenaltyForLargeCache = 4.0; static const int quality = 30; if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize) || !BackwardReferencesHashChain(xsize, ysize, argb, 0, quality, &refs)) { goto Error; } for (cache_bits = 0; cache_bits <= MAX_COLOR_CACHE_BITS; ++cache_bits) { double cur_entropy; VP8LHistogram histo; VP8LHistogramInit(&histo, cache_bits); ComputeCacheHistogram(argb, xsize, ysize, &refs, cache_bits, &histo); cur_entropy = VP8LHistogramEstimateBits(&histo) + kSmallPenaltyForLargeCache * cache_bits; if (cache_bits == 0 || cur_entropy < lowest_entropy) { *best_cache_bits = cache_bits; lowest_entropy = cur_entropy; } } ok = 1; Error: VP8LClearBackwardRefs(&refs); return ok; } libwebp-0.4.0/src/enc/alpha.c0000644000014400001440000003350612255002107012635 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Alpha-plane compression. // // Author: Skal (pascal.massimino@gmail.com) #include #include #include "./vp8enci.h" #include "../utils/filters.h" #include "../utils/quant_levels.h" #include "../webp/format_constants.h" // ----------------------------------------------------------------------------- // Encodes the given alpha data via specified compression method 'method'. // The pre-processing (quantization) is performed if 'quality' is less than 100. // For such cases, the encoding is lossy. The valid range is [0, 100] for // 'quality' and [0, 1] for 'method': // 'method = 0' - No compression; // 'method = 1' - Use lossless coder on the alpha plane only // 'filter' values [0, 4] correspond to prediction modes none, horizontal, // vertical & gradient filters. The prediction mode 4 will try all the // prediction modes 0 to 3 and pick the best one. // 'effort_level': specifies how much effort must be spent to try and reduce // the compressed output size. In range 0 (quick) to 6 (slow). // // 'output' corresponds to the buffer containing compressed alpha data. // This buffer is allocated by this method and caller should call // free(*output) when done. // 'output_size' corresponds to size of this compressed alpha buffer. // // Returns 1 on successfully encoding the alpha and // 0 if either: // invalid quality or method, or // memory allocation for the compressed data fails. #include "../enc/vp8li.h" static int EncodeLossless(const uint8_t* const data, int width, int height, int effort_level, // in [0..6] range VP8BitWriter* const bw, WebPAuxStats* const stats) { int ok = 0; WebPConfig config; WebPPicture picture; VP8LBitWriter tmp_bw; WebPPictureInit(&picture); picture.width = width; picture.height = height; picture.use_argb = 1; picture.stats = stats; if (!WebPPictureAlloc(&picture)) return 0; // Transfer the alpha values to the green channel. { int i, j; uint32_t* dst = picture.argb; const uint8_t* src = data; for (j = 0; j < picture.height; ++j) { for (i = 0; i < picture.width; ++i) { dst[i] = src[i] << 8; // we leave A/R/B channels zero'd. } src += width; dst += picture.argb_stride; } } WebPConfigInit(&config); config.lossless = 1; config.method = effort_level; // impact is very small // Set a low default quality for encoding alpha. Ensure that Alpha quality at // lower methods (3 and below) is less than the threshold for triggering // costly 'BackwardReferencesTraceBackwards'. config.quality = 8.f * effort_level; assert(config.quality >= 0 && config.quality <= 100.f); ok = VP8LBitWriterInit(&tmp_bw, (width * height) >> 3); ok = ok && (VP8LEncodeStream(&config, &picture, &tmp_bw) == VP8_ENC_OK); WebPPictureFree(&picture); if (ok) { const uint8_t* const buffer = VP8LBitWriterFinish(&tmp_bw); const size_t buffer_size = VP8LBitWriterNumBytes(&tmp_bw); VP8BitWriterAppend(bw, buffer, buffer_size); } VP8LBitWriterDestroy(&tmp_bw); return ok && !bw->error_; } // ----------------------------------------------------------------------------- // Small struct to hold the result of a filter mode compression attempt. typedef struct { size_t score; VP8BitWriter bw; WebPAuxStats stats; } FilterTrial; // This function always returns an initialized 'bw' object, even upon error. static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, int method, int filter, int reduce_levels, int effort_level, // in [0..6] range uint8_t* const tmp_alpha, FilterTrial* result) { int ok = 0; const uint8_t* alpha_src; WebPFilterFunc filter_func; uint8_t header; size_t expected_size; const size_t data_size = width * height; assert((uint64_t)data_size == (uint64_t)width * height); // as per spec assert(filter >= 0 && filter < WEBP_FILTER_LAST); assert(method >= ALPHA_NO_COMPRESSION); assert(method <= ALPHA_LOSSLESS_COMPRESSION); assert(sizeof(header) == ALPHA_HEADER_LEN); // TODO(skal): have a common function and #define's to validate alpha params. expected_size = (method == ALPHA_NO_COMPRESSION) ? (ALPHA_HEADER_LEN + data_size) : (data_size >> 5); header = method | (filter << 2); if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4; VP8BitWriterInit(&result->bw, expected_size); VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN); filter_func = WebPFilters[filter]; if (filter_func != NULL) { filter_func(data, width, height, width, tmp_alpha); alpha_src = tmp_alpha; } else { alpha_src = data; } if (method == ALPHA_NO_COMPRESSION) { ok = VP8BitWriterAppend(&result->bw, alpha_src, width * height); ok = ok && !result->bw.error_; } else { ok = EncodeLossless(alpha_src, width, height, effort_level, &result->bw, &result->stats); VP8BitWriterFinish(&result->bw); } result->score = VP8BitWriterSize(&result->bw); return ok; } // ----------------------------------------------------------------------------- // TODO(skal): move to dsp/ ? static void CopyPlane(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width, int height) { while (height-- > 0) { memcpy(dst, src, width); src += src_stride; dst += dst_stride; } } static int GetNumColors(const uint8_t* data, int width, int height, int stride) { int j; int colors = 0; uint8_t color[256] = { 0 }; for (j = 0; j < height; ++j) { int i; const uint8_t* const p = data + j * stride; for (i = 0; i < width; ++i) { color[p[i]] = 1; } } for (j = 0; j < 256; ++j) { if (color[j] > 0) ++colors; } return colors; } #define FILTER_TRY_NONE (1 << WEBP_FILTER_NONE) #define FILTER_TRY_ALL ((1 << WEBP_FILTER_LAST) - 1) // Given the input 'filter' option, return an OR'd bit-set of filters to try. static uint32_t GetFilterMap(const uint8_t* alpha, int width, int height, int filter, int effort_level) { uint32_t bit_map = 0U; if (filter == WEBP_FILTER_FAST) { // Quick estimate of the best candidate. int try_filter_none = (effort_level > 3); const int kMinColorsForFilterNone = 16; const int kMaxColorsForFilterNone = 192; const int num_colors = GetNumColors(alpha, width, height, width); // For low number of colors, NONE yields better compression. filter = (num_colors <= kMinColorsForFilterNone) ? WEBP_FILTER_NONE : EstimateBestFilter(alpha, width, height, width); bit_map |= 1 << filter; // For large number of colors, try FILTER_NONE in addition to the best // filter as well. if (try_filter_none || num_colors > kMaxColorsForFilterNone) { bit_map |= FILTER_TRY_NONE; } } else if (filter == WEBP_FILTER_NONE) { bit_map = FILTER_TRY_NONE; } else { // WEBP_FILTER_BEST -> try all bit_map = FILTER_TRY_ALL; } return bit_map; } static void InitFilterTrial(FilterTrial* const score) { score->score = (size_t)~0U; VP8BitWriterInit(&score->bw, 0); } static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height, size_t data_size, int method, int filter, int reduce_levels, int effort_level, uint8_t** const output, size_t* const output_size, WebPAuxStats* const stats) { int ok = 1; FilterTrial best; uint32_t try_map = GetFilterMap(alpha, width, height, filter, effort_level); InitFilterTrial(&best); if (try_map != FILTER_TRY_NONE) { uint8_t* filtered_alpha = (uint8_t*)malloc(data_size); if (filtered_alpha == NULL) return 0; for (filter = WEBP_FILTER_NONE; ok && try_map; ++filter, try_map >>= 1) { if (try_map & 1) { FilterTrial trial; ok = EncodeAlphaInternal(alpha, width, height, method, filter, reduce_levels, effort_level, filtered_alpha, &trial); if (ok && trial.score < best.score) { VP8BitWriterWipeOut(&best.bw); best = trial; } else { VP8BitWriterWipeOut(&trial.bw); } } } free(filtered_alpha); } else { ok = EncodeAlphaInternal(alpha, width, height, method, WEBP_FILTER_NONE, reduce_levels, effort_level, NULL, &best); } if (ok) { if (stats != NULL) *stats = best.stats; *output_size = VP8BitWriterSize(&best.bw); *output = VP8BitWriterBuf(&best.bw); } else { VP8BitWriterWipeOut(&best.bw); } return ok; } static int EncodeAlpha(VP8Encoder* const enc, int quality, int method, int filter, int effort_level, uint8_t** const output, size_t* const output_size) { const WebPPicture* const pic = enc->pic_; const int width = pic->width; const int height = pic->height; uint8_t* quant_alpha = NULL; const size_t data_size = width * height; uint64_t sse = 0; int ok = 1; const int reduce_levels = (quality < 100); // quick sanity checks assert((uint64_t)data_size == (uint64_t)width * height); // as per spec assert(enc != NULL && pic != NULL && pic->a != NULL); assert(output != NULL && output_size != NULL); assert(width > 0 && height > 0); assert(pic->a_stride >= width); assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST); if (quality < 0 || quality > 100) { return 0; } if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) { return 0; } if (method == ALPHA_NO_COMPRESSION) { // Don't filter, as filtering will make no impact on compressed size. filter = WEBP_FILTER_NONE; } quant_alpha = (uint8_t*)malloc(data_size); if (quant_alpha == NULL) { return 0; } // Extract alpha data (width x height) from raw_data (stride x height). CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height); if (reduce_levels) { // No Quantization required for 'quality = 100'. // 16 alpha levels gives quite a low MSE w.r.t original alpha plane hence // mapped to moderate quality 70. Hence Quality:[0, 70] -> Levels:[2, 16] // and Quality:]70, 100] -> Levels:]16, 256]. const int alpha_levels = (quality <= 70) ? (2 + quality / 5) : (16 + (quality - 70) * 8); ok = QuantizeLevels(quant_alpha, width, height, alpha_levels, &sse); } if (ok) { ok = ApplyFiltersAndEncode(quant_alpha, width, height, data_size, method, filter, reduce_levels, effort_level, output, output_size, pic->stats); if (pic->stats != NULL) { // need stats? pic->stats->coded_size += (int)(*output_size); enc->sse_[3] = sse; } } free(quant_alpha); return ok; } //------------------------------------------------------------------------------ // Main calls static int CompressAlphaJob(VP8Encoder* const enc, void* dummy) { const WebPConfig* config = enc->config_; uint8_t* alpha_data = NULL; size_t alpha_size = 0; const int effort_level = config->method; // maps to [0..6] const WEBP_FILTER_TYPE filter = (config->alpha_filtering == 0) ? WEBP_FILTER_NONE : (config->alpha_filtering == 1) ? WEBP_FILTER_FAST : WEBP_FILTER_BEST; if (!EncodeAlpha(enc, config->alpha_quality, config->alpha_compression, filter, effort_level, &alpha_data, &alpha_size)) { return 0; } if (alpha_size != (uint32_t)alpha_size) { // Sanity check. free(alpha_data); return 0; } enc->alpha_data_size_ = (uint32_t)alpha_size; enc->alpha_data_ = alpha_data; (void)dummy; return 1; } void VP8EncInitAlpha(VP8Encoder* const enc) { enc->has_alpha_ = WebPPictureHasTransparency(enc->pic_); enc->alpha_data_ = NULL; enc->alpha_data_size_ = 0; if (enc->thread_level_ > 0) { WebPWorker* const worker = &enc->alpha_worker_; WebPWorkerInit(worker); worker->data1 = enc; worker->data2 = NULL; worker->hook = (WebPWorkerHook)CompressAlphaJob; } } int VP8EncStartAlpha(VP8Encoder* const enc) { if (enc->has_alpha_) { if (enc->thread_level_ > 0) { WebPWorker* const worker = &enc->alpha_worker_; if (!WebPWorkerReset(worker)) { // Makes sure worker is good to go. return 0; } WebPWorkerLaunch(worker); return 1; } else { return CompressAlphaJob(enc, NULL); // just do the job right away } } return 1; } int VP8EncFinishAlpha(VP8Encoder* const enc) { if (enc->has_alpha_) { if (enc->thread_level_ > 0) { WebPWorker* const worker = &enc->alpha_worker_; if (!WebPWorkerSync(worker)) return 0; // error } } return WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); } int VP8EncDeleteAlpha(VP8Encoder* const enc) { int ok = 1; if (enc->thread_level_ > 0) { WebPWorker* const worker = &enc->alpha_worker_; ok = WebPWorkerSync(worker); // finish anything left in flight WebPWorkerEnd(worker); // still need to end the worker, even if !ok } free(enc->alpha_data_); enc->alpha_data_ = NULL; enc->alpha_data_size_ = 0; enc->has_alpha_ = 0; return ok; } libwebp-0.4.0/src/enc/cost.h0000644000014400001440000000321712255002107012521 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Cost tables for level and modes. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_ENC_COST_H_ #define WEBP_ENC_COST_H_ #include "./vp8enci.h" #ifdef __cplusplus extern "C" { #endif // approximate cost per level: extern const uint16_t VP8LevelFixedCosts[MAX_LEVEL + 1]; extern const uint16_t VP8EntropyCost[256]; // 8bit fixed-point log(p) // Cost of coding one event with probability 'proba'. static WEBP_INLINE int VP8BitCost(int bit, uint8_t proba) { return !bit ? VP8EntropyCost[proba] : VP8EntropyCost[255 - proba]; } // Level cost calculations extern const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2]; void VP8CalculateLevelCosts(VP8Proba* const proba); static WEBP_INLINE int VP8LevelCost(const uint16_t* const table, int level) { return VP8LevelFixedCosts[level] + table[(level > MAX_VARIABLE_LEVEL) ? MAX_VARIABLE_LEVEL : level]; } // Mode costs extern const uint16_t VP8FixedCostsUV[4]; extern const uint16_t VP8FixedCostsI16[4]; extern const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES]; //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_ENC_COST_H_ */ libwebp-0.4.0/src/enc/Makefile.in0000644000014400001440000011526712255206714013470 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ subdir = src/enc DIST_COMMON = $(libwebpencodeinclude_HEADERS) $(noinst_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libwebpencode_la_LIBADD = am_libwebpencode_la_OBJECTS = libwebpencode_la-alpha.lo \ libwebpencode_la-analysis.lo \ libwebpencode_la-backward_references.lo \ libwebpencode_la-config.lo libwebpencode_la-cost.lo \ libwebpencode_la-filter.lo libwebpencode_la-frame.lo \ libwebpencode_la-histogram.lo libwebpencode_la-iterator.lo \ libwebpencode_la-layer.lo libwebpencode_la-picture.lo \ libwebpencode_la-quant.lo libwebpencode_la-syntax.lo \ libwebpencode_la-token.lo libwebpencode_la-tree.lo \ libwebpencode_la-vp8l.lo libwebpencode_la-webpenc.lo libwebpencode_la_OBJECTS = $(am_libwebpencode_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libwebpencode_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libwebpencode_la_LDFLAGS) $(LDFLAGS) \ -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebpencode_la_SOURCES) DIST_SOURCES = $(libwebpencode_la_SOURCES) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libwebpencodeincludedir)" HEADERS = $(libwebpencodeinclude_HEADERS) $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebpencode.la libwebpencode_la_SOURCES = alpha.c analysis.c backward_references.c \ config.c cost.c cost.h filter.c frame.c histogram.c iterator.c \ layer.c picture.c quant.c syntax.c token.c tree.c vp8enci.h \ vp8l.c webpenc.c libwebpencodeinclude_HEADERS = ../webp/encode.h ../webp/types.h noinst_HEADERS = ../webp/format_constants.h libwebpencode_la_LDFLAGS = -lm libwebpencode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) libwebpencodeincludedir = $(includedir)/webp all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/enc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/enc/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebpencode.la: $(libwebpencode_la_OBJECTS) $(libwebpencode_la_DEPENDENCIES) $(EXTRA_libwebpencode_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebpencode_la_LINK) $(libwebpencode_la_OBJECTS) $(libwebpencode_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-alpha.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-analysis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-backward_references.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-cost.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-filter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-frame.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-histogram.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-iterator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-layer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-picture.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-quant.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-syntax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-token.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-tree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-vp8l.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-webpenc.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 $@ $< libwebpencode_la-alpha.lo: alpha.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-alpha.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-alpha.Tpo -c -o libwebpencode_la-alpha.lo `test -f 'alpha.c' || echo '$(srcdir)/'`alpha.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-alpha.Tpo $(DEPDIR)/libwebpencode_la-alpha.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha.c' object='libwebpencode_la-alpha.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-alpha.lo `test -f 'alpha.c' || echo '$(srcdir)/'`alpha.c libwebpencode_la-analysis.lo: analysis.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-analysis.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-analysis.Tpo -c -o libwebpencode_la-analysis.lo `test -f 'analysis.c' || echo '$(srcdir)/'`analysis.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-analysis.Tpo $(DEPDIR)/libwebpencode_la-analysis.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='analysis.c' object='libwebpencode_la-analysis.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-analysis.lo `test -f 'analysis.c' || echo '$(srcdir)/'`analysis.c libwebpencode_la-backward_references.lo: backward_references.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-backward_references.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-backward_references.Tpo -c -o libwebpencode_la-backward_references.lo `test -f 'backward_references.c' || echo '$(srcdir)/'`backward_references.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-backward_references.Tpo $(DEPDIR)/libwebpencode_la-backward_references.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backward_references.c' object='libwebpencode_la-backward_references.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-backward_references.lo `test -f 'backward_references.c' || echo '$(srcdir)/'`backward_references.c libwebpencode_la-config.lo: config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-config.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-config.Tpo -c -o libwebpencode_la-config.lo `test -f 'config.c' || echo '$(srcdir)/'`config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-config.Tpo $(DEPDIR)/libwebpencode_la-config.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config.c' object='libwebpencode_la-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-config.lo `test -f 'config.c' || echo '$(srcdir)/'`config.c libwebpencode_la-cost.lo: cost.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-cost.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-cost.Tpo -c -o libwebpencode_la-cost.lo `test -f 'cost.c' || echo '$(srcdir)/'`cost.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-cost.Tpo $(DEPDIR)/libwebpencode_la-cost.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost.c' object='libwebpencode_la-cost.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-cost.lo `test -f 'cost.c' || echo '$(srcdir)/'`cost.c libwebpencode_la-filter.lo: filter.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-filter.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-filter.Tpo -c -o libwebpencode_la-filter.lo `test -f 'filter.c' || echo '$(srcdir)/'`filter.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-filter.Tpo $(DEPDIR)/libwebpencode_la-filter.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter.c' object='libwebpencode_la-filter.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-filter.lo `test -f 'filter.c' || echo '$(srcdir)/'`filter.c libwebpencode_la-frame.lo: frame.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-frame.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-frame.Tpo -c -o libwebpencode_la-frame.lo `test -f 'frame.c' || echo '$(srcdir)/'`frame.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-frame.Tpo $(DEPDIR)/libwebpencode_la-frame.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame.c' object='libwebpencode_la-frame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-frame.lo `test -f 'frame.c' || echo '$(srcdir)/'`frame.c libwebpencode_la-histogram.lo: histogram.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-histogram.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-histogram.Tpo -c -o libwebpencode_la-histogram.lo `test -f 'histogram.c' || echo '$(srcdir)/'`histogram.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-histogram.Tpo $(DEPDIR)/libwebpencode_la-histogram.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='histogram.c' object='libwebpencode_la-histogram.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-histogram.lo `test -f 'histogram.c' || echo '$(srcdir)/'`histogram.c libwebpencode_la-iterator.lo: iterator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-iterator.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-iterator.Tpo -c -o libwebpencode_la-iterator.lo `test -f 'iterator.c' || echo '$(srcdir)/'`iterator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-iterator.Tpo $(DEPDIR)/libwebpencode_la-iterator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iterator.c' object='libwebpencode_la-iterator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-iterator.lo `test -f 'iterator.c' || echo '$(srcdir)/'`iterator.c libwebpencode_la-layer.lo: layer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-layer.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-layer.Tpo -c -o libwebpencode_la-layer.lo `test -f 'layer.c' || echo '$(srcdir)/'`layer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-layer.Tpo $(DEPDIR)/libwebpencode_la-layer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='layer.c' object='libwebpencode_la-layer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-layer.lo `test -f 'layer.c' || echo '$(srcdir)/'`layer.c libwebpencode_la-picture.lo: picture.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-picture.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-picture.Tpo -c -o libwebpencode_la-picture.lo `test -f 'picture.c' || echo '$(srcdir)/'`picture.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-picture.Tpo $(DEPDIR)/libwebpencode_la-picture.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='picture.c' object='libwebpencode_la-picture.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-picture.lo `test -f 'picture.c' || echo '$(srcdir)/'`picture.c libwebpencode_la-quant.lo: quant.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-quant.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-quant.Tpo -c -o libwebpencode_la-quant.lo `test -f 'quant.c' || echo '$(srcdir)/'`quant.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-quant.Tpo $(DEPDIR)/libwebpencode_la-quant.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quant.c' object='libwebpencode_la-quant.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-quant.lo `test -f 'quant.c' || echo '$(srcdir)/'`quant.c libwebpencode_la-syntax.lo: syntax.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-syntax.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-syntax.Tpo -c -o libwebpencode_la-syntax.lo `test -f 'syntax.c' || echo '$(srcdir)/'`syntax.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-syntax.Tpo $(DEPDIR)/libwebpencode_la-syntax.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syntax.c' object='libwebpencode_la-syntax.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-syntax.lo `test -f 'syntax.c' || echo '$(srcdir)/'`syntax.c libwebpencode_la-token.lo: token.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-token.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-token.Tpo -c -o libwebpencode_la-token.lo `test -f 'token.c' || echo '$(srcdir)/'`token.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-token.Tpo $(DEPDIR)/libwebpencode_la-token.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='token.c' object='libwebpencode_la-token.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-token.lo `test -f 'token.c' || echo '$(srcdir)/'`token.c libwebpencode_la-tree.lo: tree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-tree.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-tree.Tpo -c -o libwebpencode_la-tree.lo `test -f 'tree.c' || echo '$(srcdir)/'`tree.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-tree.Tpo $(DEPDIR)/libwebpencode_la-tree.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tree.c' object='libwebpencode_la-tree.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-tree.lo `test -f 'tree.c' || echo '$(srcdir)/'`tree.c libwebpencode_la-vp8l.lo: vp8l.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-vp8l.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-vp8l.Tpo -c -o libwebpencode_la-vp8l.lo `test -f 'vp8l.c' || echo '$(srcdir)/'`vp8l.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-vp8l.Tpo $(DEPDIR)/libwebpencode_la-vp8l.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vp8l.c' object='libwebpencode_la-vp8l.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-vp8l.lo `test -f 'vp8l.c' || echo '$(srcdir)/'`vp8l.c libwebpencode_la-webpenc.lo: webpenc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-webpenc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-webpenc.Tpo -c -o libwebpencode_la-webpenc.lo `test -f 'webpenc.c' || echo '$(srcdir)/'`webpenc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-webpenc.Tpo $(DEPDIR)/libwebpencode_la-webpenc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='webpenc.c' object='libwebpencode_la-webpenc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-webpenc.lo `test -f 'webpenc.c' || echo '$(srcdir)/'`webpenc.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-libwebpencodeincludeHEADERS: $(libwebpencodeinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(libwebpencodeincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libwebpencodeincludedir)" @list='$(libwebpencodeinclude_HEADERS)'; test -n "$(libwebpencodeincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpencodeincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpencodeincludedir)" || exit $$?; \ done uninstall-libwebpencodeincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libwebpencodeinclude_HEADERS)'; test -n "$(libwebpencodeincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libwebpencodeincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libwebpencodeincludedir)"; 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-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-libwebpencodeincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: 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 -rf ./$(DEPDIR) -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-libwebpencodeincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags 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-libwebpencodeincludeHEADERS 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 uninstall uninstall-am \ uninstall-libwebpencodeincludeHEADERS # 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: libwebp-0.4.0/src/enc/config.c0000644000014400001440000001100112255002107012777 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Coding tools configuration // // Author: Skal (pascal.massimino@gmail.com) #include "../webp/encode.h" //------------------------------------------------------------------------------ // WebPConfig //------------------------------------------------------------------------------ int WebPConfigInitInternal(WebPConfig* config, WebPPreset preset, float quality, int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) { return 0; // caller/system version mismatch! } if (config == NULL) return 0; config->quality = quality; config->target_size = 0; config->target_PSNR = 0.; config->method = 4; config->sns_strength = 50; config->filter_strength = 60; // mid-filtering config->filter_sharpness = 0; config->filter_type = 1; // default: strong (so U/V is filtered too) config->partitions = 0; config->segments = 4; config->pass = 1; config->show_compressed = 0; config->preprocessing = 0; config->autofilter = 0; config->partition_limit = 0; config->alpha_compression = 1; config->alpha_filtering = 1; config->alpha_quality = 100; config->lossless = 0; config->image_hint = WEBP_HINT_DEFAULT; config->emulate_jpeg_size = 0; config->thread_level = 0; config->low_memory = 0; // TODO(skal): tune. switch (preset) { case WEBP_PRESET_PICTURE: config->sns_strength = 80; config->filter_sharpness = 4; config->filter_strength = 35; config->preprocessing &= ~2; // no dithering break; case WEBP_PRESET_PHOTO: config->sns_strength = 80; config->filter_sharpness = 3; config->filter_strength = 30; config->preprocessing |= 2; break; case WEBP_PRESET_DRAWING: config->sns_strength = 25; config->filter_sharpness = 6; config->filter_strength = 10; break; case WEBP_PRESET_ICON: config->sns_strength = 0; config->filter_strength = 0; // disable filtering to retain sharpness config->preprocessing &= ~2; // no dithering break; case WEBP_PRESET_TEXT: config->sns_strength = 0; config->filter_strength = 0; // disable filtering to retain sharpness config->preprocessing &= ~2; // no dithering config->segments = 2; break; case WEBP_PRESET_DEFAULT: default: break; } return WebPValidateConfig(config); } int WebPValidateConfig(const WebPConfig* config) { if (config == NULL) return 0; if (config->quality < 0 || config->quality > 100) return 0; if (config->target_size < 0) return 0; if (config->target_PSNR < 0) return 0; if (config->method < 0 || config->method > 6) return 0; if (config->segments < 1 || config->segments > 4) return 0; if (config->sns_strength < 0 || config->sns_strength > 100) return 0; if (config->filter_strength < 0 || config->filter_strength > 100) return 0; if (config->filter_sharpness < 0 || config->filter_sharpness > 7) return 0; if (config->filter_type < 0 || config->filter_type > 1) return 0; if (config->autofilter < 0 || config->autofilter > 1) return 0; if (config->pass < 1 || config->pass > 10) return 0; if (config->show_compressed < 0 || config->show_compressed > 1) return 0; if (config->preprocessing < 0 || config->preprocessing > 3) return 0; if (config->partitions < 0 || config->partitions > 3) return 0; if (config->partition_limit < 0 || config->partition_limit > 100) return 0; if (config->alpha_compression < 0) return 0; if (config->alpha_filtering < 0) return 0; if (config->alpha_quality < 0 || config->alpha_quality > 100) return 0; if (config->lossless < 0 || config->lossless > 1) return 0; if (config->image_hint >= WEBP_HINT_LAST) return 0; if (config->emulate_jpeg_size < 0 || config->emulate_jpeg_size > 1) return 0; if (config->thread_level < 0 || config->thread_level > 1) return 0; if (config->low_memory < 0 || config->low_memory > 1) return 0; return 1; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/filter.c0000644000014400001440000004117412255002107013035 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Selecting filter level // // Author: somnath@google.com (Somnath Banerjee) #include #include "./vp8enci.h" // This table gives, for a given sharpness, the filtering strength to be // used (at least) in order to filter a given edge step delta. // This is constructed by brute force inspection: for all delta, we iterate // over all possible filtering strength / thresh until needs_filter() returns // true. #define MAX_DELTA_SIZE 64 static const uint8_t kLevelsFromDelta[8][MAX_DELTA_SIZE] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 }, { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }, { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }, { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45, 46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 61, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }, { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }, { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }, { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45, 46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 61, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }, { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 } }; int VP8FilterStrengthFromDelta(int sharpness, int delta) { const int pos = (delta < MAX_DELTA_SIZE) ? delta : MAX_DELTA_SIZE - 1; assert(sharpness >= 0 && sharpness <= 7); return kLevelsFromDelta[sharpness][pos]; } // ----------------------------------------------------------------------------- // NOTE: clip1, tables and InitTables are repeated entries of dsp.c static uint8_t abs0[255 + 255 + 1]; // abs(i) static uint8_t abs1[255 + 255 + 1]; // abs(i)>>1 static int8_t sclip1[1020 + 1020 + 1]; // clips [-1020, 1020] to [-128, 127] static int8_t sclip2[112 + 112 + 1]; // clips [-112, 112] to [-16, 15] static uint8_t clip1[255 + 510 + 1]; // clips [-255,510] to [0,255] static int tables_ok = 0; static void InitTables(void) { if (!tables_ok) { int i; for (i = -255; i <= 255; ++i) { abs0[255 + i] = (i < 0) ? -i : i; abs1[255 + i] = abs0[255 + i] >> 1; } for (i = -1020; i <= 1020; ++i) { sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i; } for (i = -112; i <= 112; ++i) { sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i; } for (i = -255; i <= 255 + 255; ++i) { clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i; } tables_ok = 1; } } //------------------------------------------------------------------------------ // Edge filtering functions // 4 pixels in, 2 pixels out static WEBP_INLINE void do_filter2(uint8_t* p, int step) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; const int a = 3 * (q0 - p0) + sclip1[1020 + p1 - q1]; const int a1 = sclip2[112 + ((a + 4) >> 3)]; const int a2 = sclip2[112 + ((a + 3) >> 3)]; p[-step] = clip1[255 + p0 + a2]; p[ 0] = clip1[255 + q0 - a1]; } // 4 pixels in, 4 pixels out static WEBP_INLINE void do_filter4(uint8_t* p, int step) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; const int a = 3 * (q0 - p0); const int a1 = sclip2[112 + ((a + 4) >> 3)]; const int a2 = sclip2[112 + ((a + 3) >> 3)]; const int a3 = (a1 + 1) >> 1; p[-2*step] = clip1[255 + p1 + a3]; p[- step] = clip1[255 + p0 + a2]; p[ 0] = clip1[255 + q0 - a1]; p[ step] = clip1[255 + q1 - a3]; } // high edge-variance static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; return (abs0[255 + p1 - p0] > thresh) || (abs0[255 + q1 - q0] > thresh); } static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int thresh) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; return (2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) <= thresh; } static WEBP_INLINE int needs_filter2(const uint8_t* p, int step, int t, int it) { const int p3 = p[-4*step], p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step]; const int q0 = p[0], q1 = p[step], q2 = p[2*step], q3 = p[3*step]; if ((2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) > t) return 0; return abs0[255 + p3 - p2] <= it && abs0[255 + p2 - p1] <= it && abs0[255 + p1 - p0] <= it && abs0[255 + q3 - q2] <= it && abs0[255 + q2 - q1] <= it && abs0[255 + q1 - q0] <= it; } //------------------------------------------------------------------------------ // Simple In-loop filtering (Paragraph 15.2) static void SimpleVFilter16(uint8_t* p, int stride, int thresh) { int i; for (i = 0; i < 16; ++i) { if (needs_filter(p + i, stride, thresh)) { do_filter2(p + i, stride); } } } static void SimpleHFilter16(uint8_t* p, int stride, int thresh) { int i; for (i = 0; i < 16; ++i) { if (needs_filter(p + i * stride, 1, thresh)) { do_filter2(p + i * stride, 1); } } } static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4 * stride; SimpleVFilter16(p, stride, thresh); } } static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4; SimpleHFilter16(p, stride, thresh); } } //------------------------------------------------------------------------------ // Complex In-loop filtering (Paragraph 15.3) static WEBP_INLINE void FilterLoop24(uint8_t* p, int hstride, int vstride, int size, int thresh, int ithresh, int hev_thresh) { while (size-- > 0) { if (needs_filter2(p, hstride, thresh, ithresh)) { if (hev(p, hstride, hev_thresh)) { do_filter2(p, hstride); } else { do_filter4(p, hstride); } } p += vstride; } } // on three inner edges static void VFilter16i(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { int k; for (k = 3; k > 0; --k) { p += 4 * stride; FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh); } } static void HFilter16i(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { int k; for (k = 3; k > 0; --k) { p += 4; FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh); } } static void VFilter8i(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh); FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh); } static void HFilter8i(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh); } //------------------------------------------------------------------------------ void (*VP8EncVFilter16i)(uint8_t*, int, int, int, int) = VFilter16i; void (*VP8EncHFilter16i)(uint8_t*, int, int, int, int) = HFilter16i; void (*VP8EncVFilter8i)(uint8_t*, uint8_t*, int, int, int, int) = VFilter8i; void (*VP8EncHFilter8i)(uint8_t*, uint8_t*, int, int, int, int) = HFilter8i; void (*VP8EncSimpleVFilter16i)(uint8_t*, int, int) = SimpleVFilter16i; void (*VP8EncSimpleHFilter16i)(uint8_t*, int, int) = SimpleHFilter16i; //------------------------------------------------------------------------------ // Paragraph 15.4: compute the inner-edge filtering strength static int GetILevel(int sharpness, int level) { if (sharpness > 0) { if (sharpness > 4) { level >>= 2; } else { level >>= 1; } if (level > 9 - sharpness) { level = 9 - sharpness; } } if (level < 1) level = 1; return level; } static void DoFilter(const VP8EncIterator* const it, int level) { const VP8Encoder* const enc = it->enc_; const int ilevel = GetILevel(enc->config_->filter_sharpness, level); const int limit = 2 * level + ilevel; uint8_t* const y_dst = it->yuv_out2_ + Y_OFF; uint8_t* const u_dst = it->yuv_out2_ + U_OFF; uint8_t* const v_dst = it->yuv_out2_ + V_OFF; // copy current block to yuv_out2_ memcpy(y_dst, it->yuv_out_, YUV_SIZE * sizeof(uint8_t)); if (enc->filter_hdr_.simple_ == 1) { // simple VP8EncSimpleHFilter16i(y_dst, BPS, limit); VP8EncSimpleVFilter16i(y_dst, BPS, limit); } else { // complex const int hev_thresh = (level >= 40) ? 2 : (level >= 15) ? 1 : 0; VP8EncHFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); VP8EncHFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); VP8EncVFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); VP8EncVFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); } } //------------------------------------------------------------------------------ // SSIM metric enum { KERNEL = 3 }; static const double kMinValue = 1.e-10; // minimal threshold void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst) { dst->w += src->w; dst->xm += src->xm; dst->ym += src->ym; dst->xxm += src->xxm; dst->xym += src->xym; dst->yym += src->yym; } static void VP8SSIMAccumulate(const uint8_t* src1, int stride1, const uint8_t* src2, int stride2, int xo, int yo, int W, int H, DistoStats* const stats) { const int ymin = (yo - KERNEL < 0) ? 0 : yo - KERNEL; const int ymax = (yo + KERNEL > H - 1) ? H - 1 : yo + KERNEL; const int xmin = (xo - KERNEL < 0) ? 0 : xo - KERNEL; const int xmax = (xo + KERNEL > W - 1) ? W - 1 : xo + KERNEL; int x, y; src1 += ymin * stride1; src2 += ymin * stride2; for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) { for (x = xmin; x <= xmax; ++x) { const int s1 = src1[x]; const int s2 = src2[x]; stats->w += 1; stats->xm += s1; stats->ym += s2; stats->xxm += s1 * s1; stats->xym += s1 * s2; stats->yym += s2 * s2; } } } double VP8SSIMGet(const DistoStats* const stats) { const double xmxm = stats->xm * stats->xm; const double ymym = stats->ym * stats->ym; const double xmym = stats->xm * stats->ym; const double w2 = stats->w * stats->w; double sxx = stats->xxm * stats->w - xmxm; double syy = stats->yym * stats->w - ymym; double sxy = stats->xym * stats->w - xmym; double C1, C2; double fnum; double fden; // small errors are possible, due to rounding. Clamp to zero. if (sxx < 0.) sxx = 0.; if (syy < 0.) syy = 0.; C1 = 6.5025 * w2; C2 = 58.5225 * w2; fnum = (2 * xmym + C1) * (2 * sxy + C2); fden = (xmxm + ymym + C1) * (sxx + syy + C2); return (fden != 0.) ? fnum / fden : kMinValue; } double VP8SSIMGetSquaredError(const DistoStats* const s) { if (s->w > 0.) { const double iw2 = 1. / (s->w * s->w); const double sxx = s->xxm * s->w - s->xm * s->xm; const double syy = s->yym * s->w - s->ym * s->ym; const double sxy = s->xym * s->w - s->xm * s->ym; const double SSE = iw2 * (sxx + syy - 2. * sxy); if (SSE > kMinValue) return SSE; } return kMinValue; } void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1, const uint8_t* src2, int stride2, int W, int H, DistoStats* const stats) { int x, y; for (y = 0; y < H; ++y) { for (x = 0; x < W; ++x) { VP8SSIMAccumulate(src1, stride1, src2, stride2, x, y, W, H, stats); } } } static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) { int x, y; DistoStats s = { .0, .0, .0, .0, .0, .0 }; // compute SSIM in a 10 x 10 window for (x = 3; x < 13; x++) { for (y = 3; y < 13; y++) { VP8SSIMAccumulate(yuv1 + Y_OFF, BPS, yuv2 + Y_OFF, BPS, x, y, 16, 16, &s); } } for (x = 1; x < 7; x++) { for (y = 1; y < 7; y++) { VP8SSIMAccumulate(yuv1 + U_OFF, BPS, yuv2 + U_OFF, BPS, x, y, 8, 8, &s); VP8SSIMAccumulate(yuv1 + V_OFF, BPS, yuv2 + V_OFF, BPS, x, y, 8, 8, &s); } } return VP8SSIMGet(&s); } //------------------------------------------------------------------------------ // Exposed APIs: Encoder should call the following 3 functions to adjust // loop filter strength void VP8InitFilter(VP8EncIterator* const it) { if (it->lf_stats_ != NULL) { int s, i; InitTables(); for (s = 0; s < NUM_MB_SEGMENTS; s++) { for (i = 0; i < MAX_LF_LEVELS; i++) { (*it->lf_stats_)[s][i] = 0; } } } } void VP8StoreFilterStats(VP8EncIterator* const it) { int d; VP8Encoder* const enc = it->enc_; const int s = it->mb_->segment_; const int level0 = enc->dqm_[s].fstrength_; // TODO: ref_lf_delta[] // explore +/-quant range of values around level0 const int delta_min = -enc->dqm_[s].quant_; const int delta_max = enc->dqm_[s].quant_; const int step_size = (delta_max - delta_min >= 4) ? 4 : 1; if (it->lf_stats_ == NULL) return; // NOTE: Currently we are applying filter only across the sublock edges // There are two reasons for that. // 1. Applying filter on macro block edges will change the pixels in // the left and top macro blocks. That will be hard to restore // 2. Macro Blocks on the bottom and right are not yet compressed. So we // cannot apply filter on the right and bottom macro block edges. if (it->mb_->type_ == 1 && it->mb_->skip_) return; // Always try filter level zero (*it->lf_stats_)[s][0] += GetMBSSIM(it->yuv_in_, it->yuv_out_); for (d = delta_min; d <= delta_max; d += step_size) { const int level = level0 + d; if (level <= 0 || level >= MAX_LF_LEVELS) { continue; } DoFilter(it, level); (*it->lf_stats_)[s][level] += GetMBSSIM(it->yuv_in_, it->yuv_out2_); } } void VP8AdjustFilterStrength(VP8EncIterator* const it) { VP8Encoder* const enc = it->enc_; if (it->lf_stats_ != NULL) { int s; for (s = 0; s < NUM_MB_SEGMENTS; s++) { int i, best_level = 0; // Improvement over filter level 0 should be at least 1e-5 (relatively) double best_v = 1.00001 * (*it->lf_stats_)[s][0]; for (i = 1; i < MAX_LF_LEVELS; i++) { const double v = (*it->lf_stats_)[s][i]; if (v > best_v) { best_v = v; best_level = i; } } enc->dqm_[s].fstrength_ = best_level; } } else if (enc->config_->filter_strength > 0) { int max_level = 0; int s; for (s = 0; s < NUM_MB_SEGMENTS; s++) { VP8SegmentInfo* const dqm = &enc->dqm_[s]; // this '>> 3' accounts for some inverse WHT scaling const int delta = (dqm->max_edge_ * dqm->y2_.q_[1]) >> 3; const int level = VP8FilterStrengthFromDelta(enc->filter_hdr_.sharpness_, delta); if (level > dqm->fstrength_) { dqm->fstrength_ = level; } if (max_level < dqm->fstrength_) { max_level = dqm->fstrength_; } } enc->filter_hdr_.level_ = max_level; } } // ----------------------------------------------------------------------------- libwebp-0.4.0/src/enc/histogram.c0000644000014400001440000004222312255002107013541 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) // #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "./backward_references.h" #include "./histogram.h" #include "../dsp/lossless.h" #include "../utils/utils.h" static void HistogramClear(VP8LHistogram* const p) { memset(p->literal_, 0, sizeof(p->literal_)); memset(p->red_, 0, sizeof(p->red_)); memset(p->blue_, 0, sizeof(p->blue_)); memset(p->alpha_, 0, sizeof(p->alpha_)); memset(p->distance_, 0, sizeof(p->distance_)); p->bit_cost_ = 0; } void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs, VP8LHistogram* const histo) { int i; for (i = 0; i < refs->size; ++i) { VP8LHistogramAddSinglePixOrCopy(histo, &refs->refs[i]); } } void VP8LHistogramCreate(VP8LHistogram* const p, const VP8LBackwardRefs* const refs, int palette_code_bits) { if (palette_code_bits >= 0) { p->palette_code_bits_ = palette_code_bits; } HistogramClear(p); VP8LHistogramStoreRefs(refs, p); } void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits) { p->palette_code_bits_ = palette_code_bits; HistogramClear(p); } VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) { int i; VP8LHistogramSet* set; VP8LHistogram* bulk; const uint64_t total_size = sizeof(*set) + (uint64_t)size * sizeof(*set->histograms) + (uint64_t)size * sizeof(**set->histograms); uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory)); if (memory == NULL) return NULL; set = (VP8LHistogramSet*)memory; memory += sizeof(*set); set->histograms = (VP8LHistogram**)memory; memory += size * sizeof(*set->histograms); bulk = (VP8LHistogram*)memory; set->max_size = size; set->size = size; for (i = 0; i < size; ++i) { set->histograms[i] = bulk + i; VP8LHistogramInit(set->histograms[i], cache_bits); } return set; } // ----------------------------------------------------------------------------- void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo, const PixOrCopy* const v) { if (PixOrCopyIsLiteral(v)) { ++histo->alpha_[PixOrCopyLiteral(v, 3)]; ++histo->red_[PixOrCopyLiteral(v, 2)]; ++histo->literal_[PixOrCopyLiteral(v, 1)]; ++histo->blue_[PixOrCopyLiteral(v, 0)]; } else if (PixOrCopyIsCacheIdx(v)) { int literal_ix = 256 + NUM_LENGTH_CODES + PixOrCopyCacheIdx(v); ++histo->literal_[literal_ix]; } else { int code, extra_bits; VP8LPrefixEncodeBits(PixOrCopyLength(v), &code, &extra_bits); ++histo->literal_[256 + code]; VP8LPrefixEncodeBits(PixOrCopyDistance(v), &code, &extra_bits); ++histo->distance_[code]; } } static double BitsEntropy(const int* const array, int n) { double retval = 0.; int sum = 0; int nonzeros = 0; int max_val = 0; int i; double mix; for (i = 0; i < n; ++i) { if (array[i] != 0) { sum += array[i]; ++nonzeros; retval -= VP8LFastSLog2(array[i]); if (max_val < array[i]) { max_val = array[i]; } } } retval += VP8LFastSLog2(sum); if (nonzeros < 5) { if (nonzeros <= 1) { return 0; } // Two symbols, they will be 0 and 1 in a Huffman code. // Let's mix in a bit of entropy to favor good clustering when // distributions of these are combined. if (nonzeros == 2) { return 0.99 * sum + 0.01 * retval; } // No matter what the entropy says, we cannot be better than min_limit // with Huffman coding. I am mixing a bit of entropy into the // min_limit since it produces much better (~0.5 %) compression results // perhaps because of better entropy clustering. if (nonzeros == 3) { mix = 0.95; } else { mix = 0.7; // nonzeros == 4. } } else { mix = 0.627; } { double min_limit = 2 * sum - max_val; min_limit = mix * min_limit + (1.0 - mix) * retval; return (retval < min_limit) ? min_limit : retval; } } // Returns the cost encode the rle-encoded entropy code. // The constants in this function are experimental. static double HuffmanCost(const int* const population, int length) { // Small bias because Huffman code length is typically not stored in // full length. static const int kHuffmanCodeOfHuffmanCodeSize = CODE_LENGTH_CODES * 3; static const double kSmallBias = 9.1; double retval = kHuffmanCodeOfHuffmanCodeSize - kSmallBias; int streak = 0; int i = 0; for (; i < length - 1; ++i) { ++streak; if (population[i] == population[i + 1]) { continue; } last_streak_hack: // population[i] points now to the symbol in the streak of same values. if (streak > 3) { if (population[i] == 0) { retval += 1.5625 + 0.234375 * streak; } else { retval += 2.578125 + 0.703125 * streak; } } else { if (population[i] == 0) { retval += 1.796875 * streak; } else { retval += 3.28125 * streak; } } streak = 0; } if (i == length - 1) { ++streak; goto last_streak_hack; } return retval; } static double PopulationCost(const int* const population, int length) { return BitsEntropy(population, length) + HuffmanCost(population, length); } static double ExtraCost(const int* const population, int length) { int i; double cost = 0.; for (i = 2; i < length - 2; ++i) cost += (i >> 1) * population[i + 2]; return cost; } // Estimates the Entropy + Huffman + other block overhead size cost. double VP8LHistogramEstimateBits(const VP8LHistogram* const p) { return PopulationCost(p->literal_, VP8LHistogramNumCodes(p)) + PopulationCost(p->red_, 256) + PopulationCost(p->blue_, 256) + PopulationCost(p->alpha_, 256) + PopulationCost(p->distance_, NUM_DISTANCE_CODES) + ExtraCost(p->literal_ + 256, NUM_LENGTH_CODES) + ExtraCost(p->distance_, NUM_DISTANCE_CODES); } double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p) { return BitsEntropy(p->literal_, VP8LHistogramNumCodes(p)) + BitsEntropy(p->red_, 256) + BitsEntropy(p->blue_, 256) + BitsEntropy(p->alpha_, 256) + BitsEntropy(p->distance_, NUM_DISTANCE_CODES) + ExtraCost(p->literal_ + 256, NUM_LENGTH_CODES) + ExtraCost(p->distance_, NUM_DISTANCE_CODES); } // ----------------------------------------------------------------------------- // Various histogram combine/cost-eval functions // Adds 'in' histogram to 'out' static void HistogramAdd(const VP8LHistogram* const in, VP8LHistogram* const out) { int i; for (i = 0; i < PIX_OR_COPY_CODES_MAX; ++i) { out->literal_[i] += in->literal_[i]; } for (i = 0; i < NUM_DISTANCE_CODES; ++i) { out->distance_[i] += in->distance_[i]; } for (i = 0; i < 256; ++i) { out->red_[i] += in->red_[i]; out->blue_[i] += in->blue_[i]; out->alpha_[i] += in->alpha_[i]; } } // Performs out = a + b, computing the cost C(a+b) - C(a) - C(b) while comparing // to the threshold value 'cost_threshold'. The score returned is // Score = C(a+b) - C(a) - C(b), where C(a) + C(b) is known and fixed. // Since the previous score passed is 'cost_threshold', we only need to compare // the partial cost against 'cost_threshold + C(a) + C(b)' to possibly bail-out // early. static double HistogramAddEval(const VP8LHistogram* const a, const VP8LHistogram* const b, VP8LHistogram* const out, double cost_threshold) { double cost = 0; const double sum_cost = a->bit_cost_ + b->bit_cost_; int i; cost_threshold += sum_cost; // palette_code_bits_ is part of the cost evaluation for literal_. // TODO(skal): remove/simplify this palette_code_bits_? out->palette_code_bits_ = (a->palette_code_bits_ > b->palette_code_bits_) ? a->palette_code_bits_ : b->palette_code_bits_; for (i = 0; i < PIX_OR_COPY_CODES_MAX; ++i) { out->literal_[i] = a->literal_[i] + b->literal_[i]; } cost += PopulationCost(out->literal_, VP8LHistogramNumCodes(out)); cost += ExtraCost(out->literal_ + 256, NUM_LENGTH_CODES); if (cost > cost_threshold) return cost; for (i = 0; i < 256; ++i) out->red_[i] = a->red_[i] + b->red_[i]; cost += PopulationCost(out->red_, 256); if (cost > cost_threshold) return cost; for (i = 0; i < 256; ++i) out->blue_[i] = a->blue_[i] + b->blue_[i]; cost += PopulationCost(out->blue_, 256); if (cost > cost_threshold) return cost; for (i = 0; i < NUM_DISTANCE_CODES; ++i) { out->distance_[i] = a->distance_[i] + b->distance_[i]; } cost += PopulationCost(out->distance_, NUM_DISTANCE_CODES); cost += ExtraCost(out->distance_, NUM_DISTANCE_CODES); if (cost > cost_threshold) return cost; for (i = 0; i < 256; ++i) out->alpha_[i] = a->alpha_[i] + b->alpha_[i]; cost += PopulationCost(out->alpha_, 256); out->bit_cost_ = cost; return cost - sum_cost; } // Same as HistogramAddEval(), except that the resulting histogram // is not stored. Only the cost C(a+b) - C(a) is evaluated. We omit // the term C(b) which is constant over all the evaluations. static double HistogramAddThresh(const VP8LHistogram* const a, const VP8LHistogram* const b, double cost_threshold) { int tmp[PIX_OR_COPY_CODES_MAX]; // <= max storage we'll need int i; double cost = -a->bit_cost_; for (i = 0; i < PIX_OR_COPY_CODES_MAX; ++i) { tmp[i] = a->literal_[i] + b->literal_[i]; } // note that the tests are ordered so that the usually largest // cost shares come first. cost += PopulationCost(tmp, VP8LHistogramNumCodes(a)); cost += ExtraCost(tmp + 256, NUM_LENGTH_CODES); if (cost > cost_threshold) return cost; for (i = 0; i < 256; ++i) tmp[i] = a->red_[i] + b->red_[i]; cost += PopulationCost(tmp, 256); if (cost > cost_threshold) return cost; for (i = 0; i < 256; ++i) tmp[i] = a->blue_[i] + b->blue_[i]; cost += PopulationCost(tmp, 256); if (cost > cost_threshold) return cost; for (i = 0; i < NUM_DISTANCE_CODES; ++i) { tmp[i] = a->distance_[i] + b->distance_[i]; } cost += PopulationCost(tmp, NUM_DISTANCE_CODES); cost += ExtraCost(tmp, NUM_DISTANCE_CODES); if (cost > cost_threshold) return cost; for (i = 0; i < 256; ++i) tmp[i] = a->alpha_[i] + b->alpha_[i]; cost += PopulationCost(tmp, 256); return cost; } // ----------------------------------------------------------------------------- static void HistogramBuildImage(int xsize, int histo_bits, const VP8LBackwardRefs* const backward_refs, VP8LHistogramSet* const image) { int i; int x = 0, y = 0; const int histo_xsize = VP8LSubSampleSize(xsize, histo_bits); VP8LHistogram** const histograms = image->histograms; assert(histo_bits > 0); for (i = 0; i < backward_refs->size; ++i) { const PixOrCopy* const v = &backward_refs->refs[i]; const int ix = (y >> histo_bits) * histo_xsize + (x >> histo_bits); VP8LHistogramAddSinglePixOrCopy(histograms[ix], v); x += PixOrCopyLength(v); while (x >= xsize) { x -= xsize; ++y; } } } static uint32_t MyRand(uint32_t *seed) { *seed *= 16807U; if (*seed == 0) { *seed = 1; } return *seed; } static int HistogramCombine(const VP8LHistogramSet* const in, VP8LHistogramSet* const out, int iter_mult, int num_pairs, int num_tries_no_success) { int ok = 0; int i, iter; uint32_t seed = 0; int tries_with_no_success = 0; int out_size = in->size; const int outer_iters = in->size * iter_mult; const int min_cluster_size = 2; VP8LHistogram* const histos = (VP8LHistogram*)malloc(2 * sizeof(*histos)); VP8LHistogram* cur_combo = histos + 0; // trial merged histogram VP8LHistogram* best_combo = histos + 1; // best merged histogram so far if (histos == NULL) goto End; // Copy histograms from in[] to out[]. assert(in->size <= out->size); for (i = 0; i < in->size; ++i) { in->histograms[i]->bit_cost_ = VP8LHistogramEstimateBits(in->histograms[i]); *out->histograms[i] = *in->histograms[i]; } // Collapse similar histograms in 'out'. for (iter = 0; iter < outer_iters && out_size >= min_cluster_size; ++iter) { double best_cost_diff = 0.; int best_idx1 = -1, best_idx2 = 1; int j; const int num_tries = (num_pairs < out_size) ? num_pairs : out_size; seed += iter; for (j = 0; j < num_tries; ++j) { double curr_cost_diff; // Choose two histograms at random and try to combine them. const uint32_t idx1 = MyRand(&seed) % out_size; const uint32_t tmp = (j & 7) + 1; const uint32_t diff = (tmp < 3) ? tmp : MyRand(&seed) % (out_size - 1); const uint32_t idx2 = (idx1 + diff + 1) % out_size; if (idx1 == idx2) { continue; } // Calculate cost reduction on combining. curr_cost_diff = HistogramAddEval(out->histograms[idx1], out->histograms[idx2], cur_combo, best_cost_diff); if (curr_cost_diff < best_cost_diff) { // found a better pair? { // swap cur/best combo histograms VP8LHistogram* const tmp_histo = cur_combo; cur_combo = best_combo; best_combo = tmp_histo; } best_cost_diff = curr_cost_diff; best_idx1 = idx1; best_idx2 = idx2; } } if (best_idx1 >= 0) { *out->histograms[best_idx1] = *best_combo; // swap best_idx2 slot with last one (which is now unused) --out_size; if (best_idx2 != out_size) { out->histograms[best_idx2] = out->histograms[out_size]; out->histograms[out_size] = NULL; // just for sanity check. } tries_with_no_success = 0; } if (++tries_with_no_success >= num_tries_no_success) { break; } } out->size = out_size; ok = 1; End: free(histos); return ok; } // ----------------------------------------------------------------------------- // Histogram refinement // What is the bit cost of moving square_histogram from cur_symbol to candidate. static double HistogramDistance(const VP8LHistogram* const square_histogram, const VP8LHistogram* const candidate, double cost_threshold) { return HistogramAddThresh(candidate, square_histogram, cost_threshold); } // Find the best 'out' histogram for each of the 'in' histograms. // Note: we assume that out[]->bit_cost_ is already up-to-date. static void HistogramRemap(const VP8LHistogramSet* const in, const VP8LHistogramSet* const out, uint16_t* const symbols) { int i; for (i = 0; i < in->size; ++i) { int best_out = 0; double best_bits = HistogramDistance(in->histograms[i], out->histograms[0], 1.e38); int k; for (k = 1; k < out->size; ++k) { const double cur_bits = HistogramDistance(in->histograms[i], out->histograms[k], best_bits); if (cur_bits < best_bits) { best_bits = cur_bits; best_out = k; } } symbols[i] = best_out; } // Recompute each out based on raw and symbols. for (i = 0; i < out->size; ++i) { HistogramClear(out->histograms[i]); } for (i = 0; i < in->size; ++i) { HistogramAdd(in->histograms[i], out->histograms[symbols[i]]); } } int VP8LGetHistoImageSymbols(int xsize, int ysize, const VP8LBackwardRefs* const refs, int quality, int histo_bits, int cache_bits, VP8LHistogramSet* const image_in, uint16_t* const histogram_symbols) { int ok = 0; const int histo_xsize = histo_bits ? VP8LSubSampleSize(xsize, histo_bits) : 1; const int histo_ysize = histo_bits ? VP8LSubSampleSize(ysize, histo_bits) : 1; const int histo_image_raw_size = histo_xsize * histo_ysize; // Heuristic params for HistogramCombine(). const int num_tries_no_success = 8 + (quality >> 1); const int iter_mult = (quality < 27) ? 1 : 1 + ((quality - 27) >> 4); const int num_pairs = (quality < 25) ? 10 : (5 * quality) >> 3; VP8LHistogramSet* const image_out = VP8LAllocateHistogramSet(histo_image_raw_size, cache_bits); if (image_out == NULL) return 0; // Build histogram image. HistogramBuildImage(xsize, histo_bits, refs, image_out); // Collapse similar histograms. if (!HistogramCombine(image_out, image_in, iter_mult, num_pairs, num_tries_no_success)) { goto Error; } // Find the optimal map from original histograms to the final ones. HistogramRemap(image_out, image_in, histogram_symbols); ok = 1; Error: free(image_out); return ok; } libwebp-0.4.0/src/enc/vp8li.h0000644000014400001440000000452412255002107012615 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Lossless encoder: internal header. // // Author: Vikas Arora (vikaas.arora@gmail.com) #ifndef WEBP_ENC_VP8LI_H_ #define WEBP_ENC_VP8LI_H_ #include "./histogram.h" #include "../utils/bit_writer.h" #include "../webp/encode.h" #include "../webp/format_constants.h" #ifdef __cplusplus extern "C" { #endif typedef struct { const WebPConfig* config_; // user configuration and parameters const WebPPicture* pic_; // input picture. uint32_t* argb_; // Transformed argb image data. uint32_t* argb_scratch_; // Scratch memory for argb rows // (used for prediction). uint32_t* transform_data_; // Scratch memory for transform data. int current_width_; // Corresponds to packed image width. // Encoding parameters derived from quality parameter. int histo_bits_; int transform_bits_; int cache_bits_; // If equal to 0, don't use color cache. // Encoding parameters derived from image characteristics. int use_cross_color_; int use_subtract_green_; int use_predict_; int use_palette_; int palette_size_; uint32_t palette_[MAX_PALETTE_SIZE]; } VP8LEncoder; //------------------------------------------------------------------------------ // internal functions. Not public. // Encodes the picture. // Returns 0 if config or picture is NULL or picture doesn't have valid argb // input. int VP8LEncodeImage(const WebPConfig* const config, const WebPPicture* const picture); // Encodes the main image stream using the supplied bit writer. WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, const WebPPicture* const picture, VP8LBitWriter* const bw); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_ENC_VP8LI_H_ */ libwebp-0.4.0/src/enc/histogram.h0000644000014400001440000000710212255002107013543 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) // // Models the histograms of literal and distance codes. #ifndef WEBP_ENC_HISTOGRAM_H_ #define WEBP_ENC_HISTOGRAM_H_ #include #include #include #include #include #include "./backward_references.h" #include "../webp/format_constants.h" #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // A simple container for histograms of data. typedef struct { // literal_ contains green literal, palette-code and // copy-length-prefix histogram int literal_[PIX_OR_COPY_CODES_MAX]; int red_[256]; int blue_[256]; int alpha_[256]; // Backward reference prefix-code histogram. int distance_[NUM_DISTANCE_CODES]; int palette_code_bits_; double bit_cost_; // cached value of VP8LHistogramEstimateBits(this) } VP8LHistogram; // Collection of histograms with fixed capacity, allocated as one // big memory chunk. Can be destroyed by simply calling 'free()'. typedef struct { int size; // number of slots currently in use int max_size; // maximum capacity VP8LHistogram** histograms; } VP8LHistogramSet; // Create the histogram. // // The input data is the PixOrCopy data, which models the literals, stop // codes and backward references (both distances and lengths). Also: if // palette_code_bits is >= 0, initialize the histogram with this value. void VP8LHistogramCreate(VP8LHistogram* const p, const VP8LBackwardRefs* const refs, int palette_code_bits); // Set the palette_code_bits and reset the stats. void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits); // Collect all the references into a histogram (without reset) void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs, VP8LHistogram* const histo); // Allocate an array of pointer to histograms, allocated and initialized // using 'cache_bits'. Return NULL in case of memory error. VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits); // Accumulate a token 'v' into a histogram. void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo, const PixOrCopy* const v); // Estimate how many bits the combined entropy of literals and distance // approximately maps to. double VP8LHistogramEstimateBits(const VP8LHistogram* const p); // This function estimates the cost in bits excluding the bits needed to // represent the entropy code itself. double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p); static WEBP_INLINE int VP8LHistogramNumCodes(const VP8LHistogram* const p) { return 256 + NUM_LENGTH_CODES + ((p->palette_code_bits_ > 0) ? (1 << p->palette_code_bits_) : 0); } // Builds the histogram image. int VP8LGetHistoImageSymbols(int xsize, int ysize, const VP8LBackwardRefs* const refs, int quality, int histogram_bits, int cache_bits, VP8LHistogramSet* const image_in, uint16_t* const histogram_symbols); #ifdef __cplusplus } #endif #endif // WEBP_ENC_HISTOGRAM_H_ libwebp-0.4.0/src/enc/quant.c0000644000014400001440000011651312255002107012700 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Quantization // // Author: Skal (pascal.massimino@gmail.com) #include #include #include // for abs() #include "./vp8enci.h" #include "./cost.h" #define DO_TRELLIS_I4 1 #define DO_TRELLIS_I16 1 // not a huge gain, but ok at low bitrate. #define DO_TRELLIS_UV 0 // disable trellis for UV. Risky. Not worth. #define USE_TDISTO 1 #define MID_ALPHA 64 // neutral value for susceptibility #define MIN_ALPHA 30 // lowest usable value for susceptibility #define MAX_ALPHA 100 // higher meaningful value for susceptibility #define SNS_TO_DQ 0.9 // Scaling constant between the sns value and the QP // power-law modulation. Must be strictly less than 1. #define I4_PENALTY 4000 // Rate-penalty for quick i4/i16 decision // number of non-zero coeffs below which we consider the block very flat // (and apply a penalty to complex predictions) #define FLATNESS_LIMIT_I16 10 // I16 mode #define FLATNESS_LIMIT_I4 3 // I4 mode #define FLATNESS_LIMIT_UV 2 // UV mode #define FLATNESS_PENALTY 140 // roughly ~1bit per block #define MULT_8B(a, b) (((a) * (b) + 128) >> 8) // #define DEBUG_BLOCK //------------------------------------------------------------------------------ #if defined(DEBUG_BLOCK) #include #include static void PrintBlockInfo(const VP8EncIterator* const it, const VP8ModeScore* const rd) { int i, j; const int is_i16 = (it->mb_->type_ == 1); printf("SOURCE / OUTPUT / ABS DELTA\n"); for (j = 0; j < 24; ++j) { if (j == 16) printf("\n"); // newline before the U/V block for (i = 0; i < 16; ++i) printf("%3d ", it->yuv_in_[i + j * BPS]); printf(" "); for (i = 0; i < 16; ++i) printf("%3d ", it->yuv_out_[i + j * BPS]); printf(" "); for (i = 0; i < 16; ++i) { printf("%1d ", abs(it->yuv_out_[i + j * BPS] - it->yuv_in_[i + j * BPS])); } printf("\n"); } printf("\nD:%d SD:%d R:%d H:%d nz:0x%x score:%d\n", (int)rd->D, (int)rd->SD, (int)rd->R, (int)rd->H, (int)rd->nz, (int)rd->score); if (is_i16) { printf("Mode: %d\n", rd->mode_i16); printf("y_dc_levels:"); for (i = 0; i < 16; ++i) printf("%3d ", rd->y_dc_levels[i]); printf("\n"); } else { printf("Modes[16]: "); for (i = 0; i < 16; ++i) printf("%d ", rd->modes_i4[i]); printf("\n"); } printf("y_ac_levels:\n"); for (j = 0; j < 16; ++j) { for (i = is_i16 ? 1 : 0; i < 16; ++i) { printf("%4d ", rd->y_ac_levels[j][i]); } printf("\n"); } printf("\n"); printf("uv_levels (mode=%d):\n", rd->mode_uv); for (j = 0; j < 8; ++j) { for (i = 0; i < 16; ++i) { printf("%4d ", rd->uv_levels[j][i]); } printf("\n"); } } #endif // DEBUG_BLOCK //------------------------------------------------------------------------------ static WEBP_INLINE int clip(int v, int m, int M) { return v < m ? m : v > M ? M : v; } static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; static const uint8_t kDcTable[128] = { 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157 }; static const uint16_t kAcTable[128] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284 }; static const uint16_t kAcTable2[128] = { 8, 8, 9, 10, 12, 13, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 62, 63, 65, 66, 68, 69, 71, 72, 74, 75, 77, 79, 80, 82, 83, 85, 86, 88, 89, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 124, 127, 130, 133, 136, 139, 142, 145, 148, 151, 155, 158, 161, 164, 167, 170, 173, 176, 179, 184, 189, 193, 198, 203, 207, 212, 217, 221, 226, 230, 235, 240, 244, 249, 254, 258, 263, 268, 274, 280, 286, 292, 299, 305, 311, 317, 323, 330, 336, 342, 348, 354, 362, 370, 379, 385, 393, 401, 409, 416, 424, 432, 440 }; static const uint8_t kBiasMatrices[3][2] = { // [luma-ac,luma-dc,chroma][dc,ac] { 96, 110 }, { 96, 108 }, { 110, 115 } }; // Sharpening by (slightly) raising the hi-frequency coeffs. // Hack-ish but helpful for mid-bitrate range. Use with care. #define SHARPEN_BITS 11 // number of descaling bits for sharpening bias static const uint8_t kFreqSharpening[16] = { 0, 30, 60, 90, 30, 60, 90, 90, 60, 90, 90, 90, 90, 90, 90, 90 }; //------------------------------------------------------------------------------ // Initialize quantization parameters in VP8Matrix // Returns the average quantizer static int ExpandMatrix(VP8Matrix* const m, int type) { int i, sum; for (i = 0; i < 2; ++i) { const int is_ac_coeff = (i > 0); const int bias = kBiasMatrices[type][is_ac_coeff]; m->iq_[i] = (1 << QFIX) / m->q_[i]; m->bias_[i] = BIAS(bias); // zthresh_ is the exact value such that QUANTDIV(coeff, iQ, B) is: // * zero if coeff <= zthresh // * non-zero if coeff > zthresh m->zthresh_[i] = ((1 << QFIX) - 1 - m->bias_[i]) / m->iq_[i]; } for (i = 2; i < 16; ++i) { m->q_[i] = m->q_[1]; m->iq_[i] = m->iq_[1]; m->bias_[i] = m->bias_[1]; m->zthresh_[i] = m->zthresh_[1]; } for (sum = 0, i = 0; i < 16; ++i) { if (type == 0) { // we only use sharpening for AC luma coeffs m->sharpen_[i] = (kFreqSharpening[i] * m->q_[i]) >> SHARPEN_BITS; } else { m->sharpen_[i] = 0; } sum += m->q_[i]; } return (sum + 8) >> 4; } static void SetupMatrices(VP8Encoder* enc) { int i; const int tlambda_scale = (enc->method_ >= 4) ? enc->config_->sns_strength : 0; const int num_segments = enc->segment_hdr_.num_segments_; for (i = 0; i < num_segments; ++i) { VP8SegmentInfo* const m = &enc->dqm_[i]; const int q = m->quant_; int q4, q16, quv; m->y1_.q_[0] = kDcTable[clip(q + enc->dq_y1_dc_, 0, 127)]; m->y1_.q_[1] = kAcTable[clip(q, 0, 127)]; m->y2_.q_[0] = kDcTable[ clip(q + enc->dq_y2_dc_, 0, 127)] * 2; m->y2_.q_[1] = kAcTable2[clip(q + enc->dq_y2_ac_, 0, 127)]; m->uv_.q_[0] = kDcTable[clip(q + enc->dq_uv_dc_, 0, 117)]; m->uv_.q_[1] = kAcTable[clip(q + enc->dq_uv_ac_, 0, 127)]; q4 = ExpandMatrix(&m->y1_, 0); q16 = ExpandMatrix(&m->y2_, 1); quv = ExpandMatrix(&m->uv_, 2); m->lambda_i4_ = (3 * q4 * q4) >> 7; m->lambda_i16_ = (3 * q16 * q16); m->lambda_uv_ = (3 * quv * quv) >> 6; m->lambda_mode_ = (1 * q4 * q4) >> 7; m->lambda_trellis_i4_ = (7 * q4 * q4) >> 3; m->lambda_trellis_i16_ = (q16 * q16) >> 2; m->lambda_trellis_uv_ = (quv *quv) << 1; m->tlambda_ = (tlambda_scale * q4) >> 5; m->min_disto_ = 10 * m->y1_.q_[0]; // quantization-aware min disto m->max_edge_ = 0; } } //------------------------------------------------------------------------------ // Initialize filtering parameters // Very small filter-strength values have close to no visual effect. So we can // save a little decoding-CPU by turning filtering off for these. #define FSTRENGTH_CUTOFF 2 static void SetupFilterStrength(VP8Encoder* const enc) { int i; // level0 is in [0..500]. Using '-f 50' as filter_strength is mid-filtering. const int level0 = 5 * enc->config_->filter_strength; for (i = 0; i < NUM_MB_SEGMENTS; ++i) { VP8SegmentInfo* const m = &enc->dqm_[i]; // We focus on the quantization of AC coeffs. const int qstep = kAcTable[clip(m->quant_, 0, 127)] >> 2; const int base_strength = VP8FilterStrengthFromDelta(enc->filter_hdr_.sharpness_, qstep); // Segments with lower complexity ('beta') will be less filtered. const int f = base_strength * level0 / (256 + m->beta_); m->fstrength_ = (f < FSTRENGTH_CUTOFF) ? 0 : (f > 63) ? 63 : f; } // We record the initial strength (mainly for the case of 1-segment only). enc->filter_hdr_.level_ = enc->dqm_[0].fstrength_; enc->filter_hdr_.simple_ = (enc->config_->filter_type == 0); enc->filter_hdr_.sharpness_ = enc->config_->filter_sharpness; } //------------------------------------------------------------------------------ // Note: if you change the values below, remember that the max range // allowed by the syntax for DQ_UV is [-16,16]. #define MAX_DQ_UV (6) #define MIN_DQ_UV (-4) // We want to emulate jpeg-like behaviour where the expected "good" quality // is around q=75. Internally, our "good" middle is around c=50. So we // map accordingly using linear piece-wise function static double QualityToCompression(double c) { const double linear_c = (c < 0.75) ? c * (2. / 3.) : 2. * c - 1.; // The file size roughly scales as pow(quantizer, 3.). Actually, the // exponent is somewhere between 2.8 and 3.2, but we're mostly interested // in the mid-quant range. So we scale the compressibility inversely to // this power-law: quant ~= compression ^ 1/3. This law holds well for // low quant. Finer modeling for high-quant would make use of kAcTable[] // more explicitly. const double v = pow(linear_c, 1 / 3.); return v; } static double QualityToJPEGCompression(double c, double alpha) { // We map the complexity 'alpha' and quality setting 'c' to a compression // exponent empirically matched to the compression curve of libjpeg6b. // On average, the WebP output size will be roughly similar to that of a // JPEG file compressed with same quality factor. const double amin = 0.30; const double amax = 0.85; const double exp_min = 0.4; const double exp_max = 0.9; const double slope = (exp_min - exp_max) / (amax - amin); // Linearly interpolate 'expn' from exp_min to exp_max // in the [amin, amax] range. const double expn = (alpha > amax) ? exp_min : (alpha < amin) ? exp_max : exp_max + slope * (alpha - amin); const double v = pow(c, expn); return v; } static int SegmentsAreEquivalent(const VP8SegmentInfo* const S1, const VP8SegmentInfo* const S2) { return (S1->quant_ == S2->quant_) && (S1->fstrength_ == S2->fstrength_); } static void SimplifySegments(VP8Encoder* const enc) { int map[NUM_MB_SEGMENTS] = { 0, 1, 2, 3 }; const int num_segments = enc->segment_hdr_.num_segments_; int num_final_segments = 1; int s1, s2; for (s1 = 1; s1 < num_segments; ++s1) { // find similar segments const VP8SegmentInfo* const S1 = &enc->dqm_[s1]; int found = 0; // check if we already have similar segment for (s2 = 0; s2 < num_final_segments; ++s2) { const VP8SegmentInfo* const S2 = &enc->dqm_[s2]; if (SegmentsAreEquivalent(S1, S2)) { found = 1; break; } } map[s1] = s2; if (!found) { if (num_final_segments != s1) { enc->dqm_[num_final_segments] = enc->dqm_[s1]; } ++num_final_segments; } } if (num_final_segments < num_segments) { // Remap int i = enc->mb_w_ * enc->mb_h_; while (i-- > 0) enc->mb_info_[i].segment_ = map[enc->mb_info_[i].segment_]; enc->segment_hdr_.num_segments_ = num_final_segments; // Replicate the trailing segment infos (it's mostly cosmetics) for (i = num_final_segments; i < num_segments; ++i) { enc->dqm_[i] = enc->dqm_[num_final_segments - 1]; } } } void VP8SetSegmentParams(VP8Encoder* const enc, float quality) { int i; int dq_uv_ac, dq_uv_dc; const int num_segments = enc->segment_hdr_.num_segments_; const double amp = SNS_TO_DQ * enc->config_->sns_strength / 100. / 128.; const double Q = quality / 100.; const double c_base = enc->config_->emulate_jpeg_size ? QualityToJPEGCompression(Q, enc->alpha_ / 255.) : QualityToCompression(Q); for (i = 0; i < num_segments; ++i) { // We modulate the base coefficient to accommodate for the quantization // susceptibility and allow denser segments to be quantized more. const double expn = 1. - amp * enc->dqm_[i].alpha_; const double c = pow(c_base, expn); const int q = (int)(127. * (1. - c)); assert(expn > 0.); enc->dqm_[i].quant_ = clip(q, 0, 127); } // purely indicative in the bitstream (except for the 1-segment case) enc->base_quant_ = enc->dqm_[0].quant_; // fill-in values for the unused segments (required by the syntax) for (i = num_segments; i < NUM_MB_SEGMENTS; ++i) { enc->dqm_[i].quant_ = enc->base_quant_; } // uv_alpha_ is normally spread around ~60. The useful range is // typically ~30 (quite bad) to ~100 (ok to decimate UV more). // We map it to the safe maximal range of MAX/MIN_DQ_UV for dq_uv. dq_uv_ac = (enc->uv_alpha_ - MID_ALPHA) * (MAX_DQ_UV - MIN_DQ_UV) / (MAX_ALPHA - MIN_ALPHA); // we rescale by the user-defined strength of adaptation dq_uv_ac = dq_uv_ac * enc->config_->sns_strength / 100; // and make it safe. dq_uv_ac = clip(dq_uv_ac, MIN_DQ_UV, MAX_DQ_UV); // We also boost the dc-uv-quant a little, based on sns-strength, since // U/V channels are quite more reactive to high quants (flat DC-blocks // tend to appear, and are displeasant). dq_uv_dc = -4 * enc->config_->sns_strength / 100; dq_uv_dc = clip(dq_uv_dc, -15, 15); // 4bit-signed max allowed enc->dq_y1_dc_ = 0; // TODO(skal): dq-lum enc->dq_y2_dc_ = 0; enc->dq_y2_ac_ = 0; enc->dq_uv_dc_ = dq_uv_dc; enc->dq_uv_ac_ = dq_uv_ac; SetupFilterStrength(enc); // initialize segments' filtering, eventually if (num_segments > 1) SimplifySegments(enc); SetupMatrices(enc); // finalize quantization matrices } //------------------------------------------------------------------------------ // Form the predictions in cache // Must be ordered using {DC_PRED, TM_PRED, V_PRED, H_PRED} as index const int VP8I16ModeOffsets[4] = { I16DC16, I16TM16, I16VE16, I16HE16 }; const int VP8UVModeOffsets[4] = { C8DC8, C8TM8, C8VE8, C8HE8 }; // Must be indexed using {B_DC_PRED -> B_HU_PRED} as index const int VP8I4ModeOffsets[NUM_BMODES] = { I4DC4, I4TM4, I4VE4, I4HE4, I4RD4, I4VR4, I4LD4, I4VL4, I4HD4, I4HU4 }; void VP8MakeLuma16Preds(const VP8EncIterator* const it) { const uint8_t* const left = it->x_ ? it->y_left_ : NULL; const uint8_t* const top = it->y_ ? it->y_top_ : NULL; VP8EncPredLuma16(it->yuv_p_, left, top); } void VP8MakeChroma8Preds(const VP8EncIterator* const it) { const uint8_t* const left = it->x_ ? it->u_left_ : NULL; const uint8_t* const top = it->y_ ? it->uv_top_ : NULL; VP8EncPredChroma8(it->yuv_p_, left, top); } void VP8MakeIntra4Preds(const VP8EncIterator* const it) { VP8EncPredLuma4(it->yuv_p_, it->i4_top_); } //------------------------------------------------------------------------------ // Quantize // Layout: // +----+ // |YYYY| 0 // |YYYY| 4 // |YYYY| 8 // |YYYY| 12 // +----+ // |UUVV| 16 // |UUVV| 20 // +----+ const int VP8Scan[16 + 4 + 4] = { // Luma 0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS, 0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * BPS, 0 + 8 * BPS, 4 + 8 * BPS, 8 + 8 * BPS, 12 + 8 * BPS, 0 + 12 * BPS, 4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS, 0 + 0 * BPS, 4 + 0 * BPS, 0 + 4 * BPS, 4 + 4 * BPS, // U 8 + 0 * BPS, 12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS // V }; //------------------------------------------------------------------------------ // Distortion measurement static const uint16_t kWeightY[16] = { 38, 32, 20, 9, 32, 28, 17, 7, 20, 17, 10, 4, 9, 7, 4, 2 }; static const uint16_t kWeightTrellis[16] = { #if USE_TDISTO == 0 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 #else 30, 27, 19, 11, 27, 24, 17, 10, 19, 17, 12, 8, 11, 10, 8, 6 #endif }; // Init/Copy the common fields in score. static void InitScore(VP8ModeScore* const rd) { rd->D = 0; rd->SD = 0; rd->R = 0; rd->H = 0; rd->nz = 0; rd->score = MAX_COST; } static void CopyScore(VP8ModeScore* const dst, const VP8ModeScore* const src) { dst->D = src->D; dst->SD = src->SD; dst->R = src->R; dst->H = src->H; dst->nz = src->nz; // note that nz is not accumulated, but just copied. dst->score = src->score; } static void AddScore(VP8ModeScore* const dst, const VP8ModeScore* const src) { dst->D += src->D; dst->SD += src->SD; dst->R += src->R; dst->H += src->H; dst->nz |= src->nz; // here, new nz bits are accumulated. dst->score += src->score; } //------------------------------------------------------------------------------ // Performs trellis-optimized quantization. // Trellis typedef struct { int prev; // best previous int level; // level int sign; // sign of coeff_i score_t cost; // bit cost score_t error; // distortion = sum of (|coeff_i| - level_i * Q_i)^2 int ctx; // context (only depends on 'level'. Could be spared.) } Node; // If a coefficient was quantized to a value Q (using a neutral bias), // we test all alternate possibilities between [Q-MIN_DELTA, Q+MAX_DELTA] // We don't test negative values though. #define MIN_DELTA 0 // how much lower level to try #define MAX_DELTA 1 // how much higher #define NUM_NODES (MIN_DELTA + 1 + MAX_DELTA) #define NODE(n, l) (nodes[(n) + 1][(l) + MIN_DELTA]) static WEBP_INLINE void SetRDScore(int lambda, VP8ModeScore* const rd) { // TODO: incorporate the "* 256" in the tables? rd->score = (rd->R + rd->H) * lambda + 256 * (rd->D + rd->SD); } static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate, score_t distortion) { return rate * lambda + 256 * distortion; } static int TrellisQuantizeBlock(const VP8EncIterator* const it, int16_t in[16], int16_t out[16], int ctx0, int coeff_type, const VP8Matrix* const mtx, int lambda) { ProbaArray* const last_costs = it->enc_->proba_.coeffs_[coeff_type]; CostArray* const costs = it->enc_->proba_.level_cost_[coeff_type]; const int first = (coeff_type == 0) ? 1 : 0; Node nodes[17][NUM_NODES]; int best_path[3] = {-1, -1, -1}; // store best-last/best-level/best-previous score_t best_score; int best_node; int last = first - 1; int n, m, p, nz; { score_t cost; score_t max_error; const int thresh = mtx->q_[1] * mtx->q_[1] / 4; const int last_proba = last_costs[VP8EncBands[first]][ctx0][0]; // compute maximal distortion. max_error = 0; for (n = first; n < 16; ++n) { const int j = kZigzag[n]; const int err = in[j] * in[j]; max_error += kWeightTrellis[j] * err; if (err > thresh) last = n; } // we don't need to go inspect up to n = 16 coeffs. We can just go up // to last + 1 (inclusive) without losing much. if (last < 15) ++last; // compute 'skip' score. This is the max score one can do. cost = VP8BitCost(0, last_proba); best_score = RDScoreTrellis(lambda, cost, max_error); // initialize source node. n = first - 1; for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) { NODE(n, m).cost = 0; NODE(n, m).error = max_error; NODE(n, m).ctx = ctx0; } } // traverse trellis. for (n = first; n <= last; ++n) { const int j = kZigzag[n]; const int Q = mtx->q_[j]; const int iQ = mtx->iq_[j]; const int B = BIAS(0x00); // neutral bias // note: it's important to take sign of the _original_ coeff, // so we don't have to consider level < 0 afterward. const int sign = (in[j] < 0); const int coeff0 = (sign ? -in[j] : in[j]) + mtx->sharpen_[j]; int level0 = QUANTDIV(coeff0, iQ, B); if (level0 > MAX_LEVEL) level0 = MAX_LEVEL; // test all alternate level values around level0. for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) { Node* const cur = &NODE(n, m); int delta_error, new_error; score_t cur_score = MAX_COST; int level = level0 + m; int last_proba; cur->sign = sign; cur->level = level; cur->ctx = (level == 0) ? 0 : (level == 1) ? 1 : 2; if (level > MAX_LEVEL || level < 0) { // node is dead? cur->cost = MAX_COST; continue; } last_proba = last_costs[VP8EncBands[n + 1]][cur->ctx][0]; // Compute delta_error = how much coding this level will // subtract as distortion to max_error new_error = coeff0 - level * Q; delta_error = kWeightTrellis[j] * (coeff0 * coeff0 - new_error * new_error); // Inspect all possible non-dead predecessors. Retain only the best one. for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) { const Node* const prev = &NODE(n - 1, p); const int prev_ctx = prev->ctx; const uint16_t* const tcost = costs[VP8EncBands[n]][prev_ctx]; const score_t total_error = prev->error - delta_error; score_t cost, base_cost, score; if (prev->cost >= MAX_COST) { // dead node? continue; } // Base cost of both terminal/non-terminal base_cost = prev->cost + VP8LevelCost(tcost, level); // Examine node assuming it's a non-terminal one. cost = base_cost; if (level && n < 15) { cost += VP8BitCost(1, last_proba); } score = RDScoreTrellis(lambda, cost, total_error); if (score < cur_score) { cur_score = score; cur->cost = cost; cur->error = total_error; cur->prev = p; } // Now, record best terminal node (and thus best entry in the graph). if (level) { cost = base_cost; if (n < 15) cost += VP8BitCost(0, last_proba); score = RDScoreTrellis(lambda, cost, total_error); if (score < best_score) { best_score = score; best_path[0] = n; // best eob position best_path[1] = m; // best level best_path[2] = p; // best predecessor } } } } } // Fresh start memset(in + first, 0, (16 - first) * sizeof(*in)); memset(out + first, 0, (16 - first) * sizeof(*out)); if (best_path[0] == -1) { return 0; // skip! } // Unwind the best path. // Note: best-prev on terminal node is not necessarily equal to the // best_prev for non-terminal. So we patch best_path[2] in. n = best_path[0]; best_node = best_path[1]; NODE(n, best_node).prev = best_path[2]; // force best-prev for terminal nz = 0; for (; n >= first; --n) { const Node* const node = &NODE(n, best_node); const int j = kZigzag[n]; out[n] = node->sign ? -node->level : node->level; nz |= (node->level != 0); in[j] = out[n] * mtx->q_[j]; best_node = node->prev; } return nz; } #undef NODE //------------------------------------------------------------------------------ // Performs: difference, transform, quantize, back-transform, add // all at once. Output is the reconstructed block in *yuv_out, and the // quantized levels in *levels. static int ReconstructIntra16(VP8EncIterator* const it, VP8ModeScore* const rd, uint8_t* const yuv_out, int mode) { VP8Encoder* const enc = it->enc_; const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode]; const uint8_t* const src = it->yuv_in_ + Y_OFF; VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; int nz = 0; int n; int16_t tmp[16][16], dc_tmp[16]; for (n = 0; n < 16; ++n) { VP8FTransform(src + VP8Scan[n], ref + VP8Scan[n], tmp[n]); } VP8FTransformWHT(tmp[0], dc_tmp); nz |= VP8EncQuantizeBlockWHT(dc_tmp, rd->y_dc_levels, &dqm->y2_) << 24; if (DO_TRELLIS_I16 && it->do_trellis_) { int x, y; VP8IteratorNzToBytes(it); for (y = 0, n = 0; y < 4; ++y) { for (x = 0; x < 4; ++x, ++n) { const int ctx = it->top_nz_[x] + it->left_nz_[y]; const int non_zero = TrellisQuantizeBlock(it, tmp[n], rd->y_ac_levels[n], ctx, 0, &dqm->y1_, dqm->lambda_trellis_i16_); it->top_nz_[x] = it->left_nz_[y] = non_zero; nz |= non_zero << n; } } } else { for (n = 0; n < 16; ++n) { nz |= VP8EncQuantizeBlock(tmp[n], rd->y_ac_levels[n], 1, &dqm->y1_) << n; } } // Transform back VP8ITransformWHT(dc_tmp, tmp[0]); for (n = 0; n < 16; n += 2) { VP8ITransform(ref + VP8Scan[n], tmp[n], yuv_out + VP8Scan[n], 1); } return nz; } static int ReconstructIntra4(VP8EncIterator* const it, int16_t levels[16], const uint8_t* const src, uint8_t* const yuv_out, int mode) { const VP8Encoder* const enc = it->enc_; const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode]; const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; int nz = 0; int16_t tmp[16]; VP8FTransform(src, ref, tmp); if (DO_TRELLIS_I4 && it->do_trellis_) { const int x = it->i4_ & 3, y = it->i4_ >> 2; const int ctx = it->top_nz_[x] + it->left_nz_[y]; nz = TrellisQuantizeBlock(it, tmp, levels, ctx, 3, &dqm->y1_, dqm->lambda_trellis_i4_); } else { nz = VP8EncQuantizeBlock(tmp, levels, 0, &dqm->y1_); } VP8ITransform(ref, tmp, yuv_out, 0); return nz; } static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd, uint8_t* const yuv_out, int mode) { const VP8Encoder* const enc = it->enc_; const uint8_t* const ref = it->yuv_p_ + VP8UVModeOffsets[mode]; const uint8_t* const src = it->yuv_in_ + U_OFF; const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; int nz = 0; int n; int16_t tmp[8][16]; for (n = 0; n < 8; ++n) { VP8FTransform(src + VP8Scan[16 + n], ref + VP8Scan[16 + n], tmp[n]); } if (DO_TRELLIS_UV && it->do_trellis_) { int ch, x, y; for (ch = 0, n = 0; ch <= 2; ch += 2) { for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x, ++n) { const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y]; const int non_zero = TrellisQuantizeBlock(it, tmp[n], rd->uv_levels[n], ctx, 2, &dqm->uv_, dqm->lambda_trellis_uv_); it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero; nz |= non_zero << n; } } } } else { for (n = 0; n < 8; ++n) { nz |= VP8EncQuantizeBlock(tmp[n], rd->uv_levels[n], 0, &dqm->uv_) << n; } } for (n = 0; n < 8; n += 2) { VP8ITransform(ref + VP8Scan[16 + n], tmp[n], yuv_out + VP8Scan[16 + n], 1); } return (nz << 16); } //------------------------------------------------------------------------------ // RD-opt decision. Reconstruct each modes, evalue distortion and bit-cost. // Pick the mode is lower RD-cost = Rate + lambda * Distortion. static void StoreMaxDelta(VP8SegmentInfo* const dqm, const int16_t DCs[16]) { // We look at the first three AC coefficients to determine what is the average // delta between each sub-4x4 block. const int v0 = abs(DCs[1]); const int v1 = abs(DCs[4]); const int v2 = abs(DCs[5]); int max_v = (v0 > v1) ? v1 : v0; max_v = (v2 > max_v) ? v2 : max_v; if (max_v > dqm->max_edge_) dqm->max_edge_ = max_v; } static void SwapPtr(uint8_t** a, uint8_t** b) { uint8_t* const tmp = *a; *a = *b; *b = tmp; } static void SwapOut(VP8EncIterator* const it) { SwapPtr(&it->yuv_out_, &it->yuv_out2_); } static score_t IsFlat(const int16_t* levels, int num_blocks, score_t thresh) { score_t score = 0; while (num_blocks-- > 0) { // TODO(skal): refine positional scoring? int i; for (i = 1; i < 16; ++i) { // omit DC, we're only interested in AC score += (levels[i] != 0); if (score > thresh) return 0; } levels += 16; } return 1; } static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* const rd) { const int kNumBlocks = 16; VP8Encoder* const enc = it->enc_; VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; const int lambda = dqm->lambda_i16_; const int tlambda = dqm->tlambda_; const uint8_t* const src = it->yuv_in_ + Y_OFF; VP8ModeScore rd16; int mode; rd->mode_i16 = -1; for (mode = 0; mode < NUM_PRED_MODES; ++mode) { uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF; // scratch buffer int nz; // Reconstruct nz = ReconstructIntra16(it, &rd16, tmp_dst, mode); // Measure RD-score rd16.D = VP8SSE16x16(src, tmp_dst); rd16.SD = tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0; rd16.H = VP8FixedCostsI16[mode]; rd16.R = VP8GetCostLuma16(it, &rd16); if (mode > 0 && IsFlat(rd16.y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) { // penalty to avoid flat area to be mispredicted by complex mode rd16.R += FLATNESS_PENALTY * kNumBlocks; } // Since we always examine Intra16 first, we can overwrite *rd directly. SetRDScore(lambda, &rd16); if (mode == 0 || rd16.score < rd->score) { CopyScore(rd, &rd16); rd->mode_i16 = mode; rd->nz = nz; memcpy(rd->y_ac_levels, rd16.y_ac_levels, sizeof(rd16.y_ac_levels)); memcpy(rd->y_dc_levels, rd16.y_dc_levels, sizeof(rd16.y_dc_levels)); SwapOut(it); } } SetRDScore(dqm->lambda_mode_, rd); // finalize score for mode decision. VP8SetIntra16Mode(it, rd->mode_i16); // we have a blocky macroblock (only DCs are non-zero) with fairly high // distortion, record max delta so we can later adjust the minimal filtering // strength needed to smooth these blocks out. if ((rd->nz & 0xffff) == 0 && rd->D > dqm->min_disto_) { StoreMaxDelta(dqm, rd->y_dc_levels); } } //------------------------------------------------------------------------------ // return the cost array corresponding to the surrounding prediction modes. static const uint16_t* GetCostModeI4(VP8EncIterator* const it, const uint8_t modes[16]) { const int preds_w = it->enc_->preds_w_; const int x = (it->i4_ & 3), y = it->i4_ >> 2; const int left = (x == 0) ? it->preds_[y * preds_w - 1] : modes[it->i4_ - 1]; const int top = (y == 0) ? it->preds_[-preds_w + x] : modes[it->i4_ - 4]; return VP8FixedCostsI4[top][left]; } static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) { const VP8Encoder* const enc = it->enc_; const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; const int lambda = dqm->lambda_i4_; const int tlambda = dqm->tlambda_; const uint8_t* const src0 = it->yuv_in_ + Y_OFF; uint8_t* const best_blocks = it->yuv_out2_ + Y_OFF; int total_header_bits = 0; VP8ModeScore rd_best; if (enc->max_i4_header_bits_ == 0) { return 0; } InitScore(&rd_best); rd_best.H = 211; // '211' is the value of VP8BitCost(0, 145) SetRDScore(dqm->lambda_mode_, &rd_best); VP8IteratorStartI4(it); do { const int kNumBlocks = 1; VP8ModeScore rd_i4; int mode; int best_mode = -1; const uint8_t* const src = src0 + VP8Scan[it->i4_]; const uint16_t* const mode_costs = GetCostModeI4(it, rd->modes_i4); uint8_t* best_block = best_blocks + VP8Scan[it->i4_]; uint8_t* tmp_dst = it->yuv_p_ + I4TMP; // scratch buffer. InitScore(&rd_i4); VP8MakeIntra4Preds(it); for (mode = 0; mode < NUM_BMODES; ++mode) { VP8ModeScore rd_tmp; int16_t tmp_levels[16]; // Reconstruct rd_tmp.nz = ReconstructIntra4(it, tmp_levels, src, tmp_dst, mode) << it->i4_; // Compute RD-score rd_tmp.D = VP8SSE4x4(src, tmp_dst); rd_tmp.SD = tlambda ? MULT_8B(tlambda, VP8TDisto4x4(src, tmp_dst, kWeightY)) : 0; rd_tmp.H = mode_costs[mode]; rd_tmp.R = VP8GetCostLuma4(it, tmp_levels); if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) { rd_tmp.R += FLATNESS_PENALTY * kNumBlocks; } SetRDScore(lambda, &rd_tmp); if (best_mode < 0 || rd_tmp.score < rd_i4.score) { CopyScore(&rd_i4, &rd_tmp); best_mode = mode; SwapPtr(&tmp_dst, &best_block); memcpy(rd_best.y_ac_levels[it->i4_], tmp_levels, sizeof(tmp_levels)); } } SetRDScore(dqm->lambda_mode_, &rd_i4); AddScore(&rd_best, &rd_i4); if (rd_best.score >= rd->score) { return 0; } total_header_bits += (int)rd_i4.H; // <- equal to mode_costs[best_mode]; if (total_header_bits > enc->max_i4_header_bits_) { return 0; } // Copy selected samples if not in the right place already. if (best_block != best_blocks + VP8Scan[it->i4_]) { VP8Copy4x4(best_block, best_blocks + VP8Scan[it->i4_]); } rd->modes_i4[it->i4_] = best_mode; it->top_nz_[it->i4_ & 3] = it->left_nz_[it->i4_ >> 2] = (rd_i4.nz ? 1 : 0); } while (VP8IteratorRotateI4(it, best_blocks)); // finalize state CopyScore(rd, &rd_best); VP8SetIntra4Mode(it, rd->modes_i4); SwapOut(it); memcpy(rd->y_ac_levels, rd_best.y_ac_levels, sizeof(rd->y_ac_levels)); return 1; // select intra4x4 over intra16x16 } //------------------------------------------------------------------------------ static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) { const int kNumBlocks = 8; const VP8Encoder* const enc = it->enc_; const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; const int lambda = dqm->lambda_uv_; const uint8_t* const src = it->yuv_in_ + U_OFF; uint8_t* const tmp_dst = it->yuv_out2_ + U_OFF; // scratch buffer uint8_t* const dst0 = it->yuv_out_ + U_OFF; VP8ModeScore rd_best; int mode; rd->mode_uv = -1; InitScore(&rd_best); for (mode = 0; mode < NUM_PRED_MODES; ++mode) { VP8ModeScore rd_uv; // Reconstruct rd_uv.nz = ReconstructUV(it, &rd_uv, tmp_dst, mode); // Compute RD-score rd_uv.D = VP8SSE16x8(src, tmp_dst); rd_uv.SD = 0; // TODO: should we call TDisto? it tends to flatten areas. rd_uv.H = VP8FixedCostsUV[mode]; rd_uv.R = VP8GetCostUV(it, &rd_uv); if (mode > 0 && IsFlat(rd_uv.uv_levels[0], kNumBlocks, FLATNESS_LIMIT_UV)) { rd_uv.R += FLATNESS_PENALTY * kNumBlocks; } SetRDScore(lambda, &rd_uv); if (mode == 0 || rd_uv.score < rd_best.score) { CopyScore(&rd_best, &rd_uv); rd->mode_uv = mode; memcpy(rd->uv_levels, rd_uv.uv_levels, sizeof(rd->uv_levels)); memcpy(dst0, tmp_dst, UV_SIZE); // TODO: SwapUVOut() ? } } VP8SetIntraUVMode(it, rd->mode_uv); AddScore(rd, &rd_best); } //------------------------------------------------------------------------------ // Final reconstruction and quantization. static void SimpleQuantize(VP8EncIterator* const it, VP8ModeScore* const rd) { const VP8Encoder* const enc = it->enc_; const int is_i16 = (it->mb_->type_ == 1); int nz = 0; if (is_i16) { nz = ReconstructIntra16(it, rd, it->yuv_out_ + Y_OFF, it->preds_[0]); } else { VP8IteratorStartI4(it); do { const int mode = it->preds_[(it->i4_ & 3) + (it->i4_ >> 2) * enc->preds_w_]; const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_]; uint8_t* const dst = it->yuv_out_ + Y_OFF + VP8Scan[it->i4_]; VP8MakeIntra4Preds(it); nz |= ReconstructIntra4(it, rd->y_ac_levels[it->i4_], src, dst, mode) << it->i4_; } while (VP8IteratorRotateI4(it, it->yuv_out_ + Y_OFF)); } nz |= ReconstructUV(it, rd, it->yuv_out_ + U_OFF, it->mb_->uv_mode_); rd->nz = nz; } // Refine intra16/intra4 sub-modes based on distortion only (not rate). static void DistoRefine(VP8EncIterator* const it, int try_both_i4_i16) { const int is_i16 = (it->mb_->type_ == 1); score_t best_score = MAX_COST; if (try_both_i4_i16 || is_i16) { int mode; int best_mode = -1; for (mode = 0; mode < NUM_PRED_MODES; ++mode) { const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode]; const uint8_t* const src = it->yuv_in_ + Y_OFF; const score_t score = VP8SSE16x16(src, ref); if (score < best_score) { best_mode = mode; best_score = score; } } VP8SetIntra16Mode(it, best_mode); } if (try_both_i4_i16 || !is_i16) { uint8_t modes_i4[16]; // We don't evaluate the rate here, but just account for it through a // constant penalty (i4 mode usually needs more bits compared to i16). score_t score_i4 = (score_t)I4_PENALTY; VP8IteratorStartI4(it); do { int mode; int best_sub_mode = -1; score_t best_sub_score = MAX_COST; const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_]; // TODO(skal): we don't really need the prediction pixels here, // but just the distortion against 'src'. VP8MakeIntra4Preds(it); for (mode = 0; mode < NUM_BMODES; ++mode) { const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode]; const score_t score = VP8SSE4x4(src, ref); if (score < best_sub_score) { best_sub_mode = mode; best_sub_score = score; } } modes_i4[it->i4_] = best_sub_mode; score_i4 += best_sub_score; if (score_i4 >= best_score) break; } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF)); if (score_i4 < best_score) { VP8SetIntra4Mode(it, modes_i4); } } } //------------------------------------------------------------------------------ // Entry point int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, VP8RDLevel rd_opt) { int is_skipped; const int method = it->enc_->method_; InitScore(rd); // We can perform predictions for Luma16x16 and Chroma8x8 already. // Luma4x4 predictions needs to be done as-we-go. VP8MakeLuma16Preds(it); VP8MakeChroma8Preds(it); if (rd_opt > RD_OPT_NONE) { it->do_trellis_ = (rd_opt >= RD_OPT_TRELLIS_ALL); PickBestIntra16(it, rd); if (method >= 2) { PickBestIntra4(it, rd); } PickBestUV(it, rd); if (rd_opt == RD_OPT_TRELLIS) { // finish off with trellis-optim now it->do_trellis_ = 1; SimpleQuantize(it, rd); } } else { // For method == 2, pick the best intra4/intra16 based on SSE (~tad slower). // For method <= 1, we refine intra4 or intra16 (but don't re-examine mode). DistoRefine(it, (method >= 2)); SimpleQuantize(it, rd); } is_skipped = (rd->nz == 0); VP8SetSkip(it, is_skipped); return is_skipped; } libwebp-0.4.0/src/enc/tree.c0000644000014400001440000005275312255002107012514 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Coding of token probabilities, intra modes and segments. // // Author: Skal (pascal.massimino@gmail.com) #include "./vp8enci.h" //------------------------------------------------------------------------------ // Default probabilities // Paragraph 13.5 const uint8_t VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = { { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 }, { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 }, { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 } }, { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 }, { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 }, { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 }, }, { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 }, { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 }, { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 }, }, { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 }, { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 }, { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 } }, { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 }, { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 }, { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 } }, { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 }, { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 }, { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 } }, { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }, { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 }, { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 }, { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 } }, { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 }, { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 }, { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 } }, { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 }, { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 }, { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 } }, { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 }, { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 }, { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 } }, { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 }, { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 }, { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 } }, { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 }, { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 }, { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 } }, { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 }, { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 }, { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 } }, { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 }, { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 }, { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 } } }, { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 }, { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 }, { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 } }, { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 }, { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 }, { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 } }, { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 }, { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 }, { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 } }, { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 }, { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 }, { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 } }, { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 }, { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 }, { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 }, { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 }, { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }, { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 }, { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 }, { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 } }, { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 }, { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 }, { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 } }, { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 }, { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 }, { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 } }, { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 }, { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 }, { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 } }, { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 }, { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 }, { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 } }, { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 }, { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 }, { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 } }, { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 }, { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 }, { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 } }, { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 } } } }; void VP8DefaultProbas(VP8Encoder* const enc) { VP8Proba* const probas = &enc->proba_; probas->use_skip_proba_ = 0; memset(probas->segments_, 255u, sizeof(probas->segments_)); memcpy(probas->coeffs_, VP8CoeffsProba0, sizeof(VP8CoeffsProba0)); // Note: we could hard-code the level_costs_ corresponding to VP8CoeffsProba0, // but that's ~11k of static data. Better call VP8CalculateLevelCosts() later. probas->dirty_ = 1; } // Paragraph 11.5. 900bytes. static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { { 231, 120, 48, 89, 115, 113, 120, 152, 112 }, { 152, 179, 64, 126, 170, 118, 46, 70, 95 }, { 175, 69, 143, 80, 85, 82, 72, 155, 103 }, { 56, 58, 10, 171, 218, 189, 17, 13, 152 }, { 114, 26, 17, 163, 44, 195, 21, 10, 173 }, { 121, 24, 80, 195, 26, 62, 44, 64, 85 }, { 144, 71, 10, 38, 171, 213, 144, 34, 26 }, { 170, 46, 55, 19, 136, 160, 33, 206, 71 }, { 63, 20, 8, 114, 114, 208, 12, 9, 226 }, { 81, 40, 11, 96, 182, 84, 29, 16, 36 } }, { { 134, 183, 89, 137, 98, 101, 106, 165, 148 }, { 72, 187, 100, 130, 157, 111, 32, 75, 80 }, { 66, 102, 167, 99, 74, 62, 40, 234, 128 }, { 41, 53, 9, 178, 241, 141, 26, 8, 107 }, { 74, 43, 26, 146, 73, 166, 49, 23, 157 }, { 65, 38, 105, 160, 51, 52, 31, 115, 128 }, { 104, 79, 12, 27, 217, 255, 87, 17, 7 }, { 87, 68, 71, 44, 114, 51, 15, 186, 23 }, { 47, 41, 14, 110, 182, 183, 21, 17, 194 }, { 66, 45, 25, 102, 197, 189, 23, 18, 22 } }, { { 88, 88, 147, 150, 42, 46, 45, 196, 205 }, { 43, 97, 183, 117, 85, 38, 35, 179, 61 }, { 39, 53, 200, 87, 26, 21, 43, 232, 171 }, { 56, 34, 51, 104, 114, 102, 29, 93, 77 }, { 39, 28, 85, 171, 58, 165, 90, 98, 64 }, { 34, 22, 116, 206, 23, 34, 43, 166, 73 }, { 107, 54, 32, 26, 51, 1, 81, 43, 31 }, { 68, 25, 106, 22, 64, 171, 36, 225, 114 }, { 34, 19, 21, 102, 132, 188, 16, 76, 124 }, { 62, 18, 78, 95, 85, 57, 50, 48, 51 } }, { { 193, 101, 35, 159, 215, 111, 89, 46, 111 }, { 60, 148, 31, 172, 219, 228, 21, 18, 111 }, { 112, 113, 77, 85, 179, 255, 38, 120, 114 }, { 40, 42, 1, 196, 245, 209, 10, 25, 109 }, { 88, 43, 29, 140, 166, 213, 37, 43, 154 }, { 61, 63, 30, 155, 67, 45, 68, 1, 209 }, { 100, 80, 8, 43, 154, 1, 51, 26, 71 }, { 142, 78, 78, 16, 255, 128, 34, 197, 171 }, { 41, 40, 5, 102, 211, 183, 4, 1, 221 }, { 51, 50, 17, 168, 209, 192, 23, 25, 82 } }, { { 138, 31, 36, 171, 27, 166, 38, 44, 229 }, { 67, 87, 58, 169, 82, 115, 26, 59, 179 }, { 63, 59, 90, 180, 59, 166, 93, 73, 154 }, { 40, 40, 21, 116, 143, 209, 34, 39, 175 }, { 47, 15, 16, 183, 34, 223, 49, 45, 183 }, { 46, 17, 33, 183, 6, 98, 15, 32, 183 }, { 57, 46, 22, 24, 128, 1, 54, 17, 37 }, { 65, 32, 73, 115, 28, 128, 23, 128, 205 }, { 40, 3, 9, 115, 51, 192, 18, 6, 223 }, { 87, 37, 9, 115, 59, 77, 64, 21, 47 } }, { { 104, 55, 44, 218, 9, 54, 53, 130, 226 }, { 64, 90, 70, 205, 40, 41, 23, 26, 57 }, { 54, 57, 112, 184, 5, 41, 38, 166, 213 }, { 30, 34, 26, 133, 152, 116, 10, 32, 134 }, { 39, 19, 53, 221, 26, 114, 32, 73, 255 }, { 31, 9, 65, 234, 2, 15, 1, 118, 73 }, { 75, 32, 12, 51, 192, 255, 160, 43, 51 }, { 88, 31, 35, 67, 102, 85, 55, 186, 85 }, { 56, 21, 23, 111, 59, 205, 45, 37, 192 }, { 55, 38, 70, 124, 73, 102, 1, 34, 98 } }, { { 125, 98, 42, 88, 104, 85, 117, 175, 82 }, { 95, 84, 53, 89, 128, 100, 113, 101, 45 }, { 75, 79, 123, 47, 51, 128, 81, 171, 1 }, { 57, 17, 5, 71, 102, 57, 53, 41, 49 }, { 38, 33, 13, 121, 57, 73, 26, 1, 85 }, { 41, 10, 67, 138, 77, 110, 90, 47, 114 }, { 115, 21, 2, 10, 102, 255, 166, 23, 6 }, { 101, 29, 16, 10, 85, 128, 101, 196, 26 }, { 57, 18, 10, 102, 102, 213, 34, 20, 43 }, { 117, 20, 15, 36, 163, 128, 68, 1, 26 } }, { { 102, 61, 71, 37, 34, 53, 31, 243, 192 }, { 69, 60, 71, 38, 73, 119, 28, 222, 37 }, { 68, 45, 128, 34, 1, 47, 11, 245, 171 }, { 62, 17, 19, 70, 146, 85, 55, 62, 70 }, { 37, 43, 37, 154, 100, 163, 85, 160, 1 }, { 63, 9, 92, 136, 28, 64, 32, 201, 85 }, { 75, 15, 9, 9, 64, 255, 184, 119, 16 }, { 86, 6, 28, 5, 64, 255, 25, 248, 1 }, { 56, 8, 17, 132, 137, 255, 55, 116, 128 }, { 58, 15, 20, 82, 135, 57, 26, 121, 40 } }, { { 164, 50, 31, 137, 154, 133, 25, 35, 218 }, { 51, 103, 44, 131, 131, 123, 31, 6, 158 }, { 86, 40, 64, 135, 148, 224, 45, 183, 128 }, { 22, 26, 17, 131, 240, 154, 14, 1, 209 }, { 45, 16, 21, 91, 64, 222, 7, 1, 197 }, { 56, 21, 39, 155, 60, 138, 23, 102, 213 }, { 83, 12, 13, 54, 192, 255, 68, 47, 28 }, { 85, 26, 85, 85, 128, 128, 32, 146, 171 }, { 18, 11, 7, 63, 144, 171, 4, 4, 246 }, { 35, 27, 10, 146, 174, 171, 12, 26, 128 } }, { { 190, 80, 35, 99, 180, 80, 126, 54, 45 }, { 85, 126, 47, 87, 176, 51, 41, 20, 32 }, { 101, 75, 128, 139, 118, 146, 116, 128, 85 }, { 56, 41, 15, 176, 236, 85, 37, 9, 62 }, { 71, 30, 17, 119, 118, 255, 17, 18, 138 }, { 101, 38, 60, 138, 55, 70, 43, 26, 142 }, { 146, 36, 19, 30, 171, 255, 97, 27, 20 }, { 138, 45, 61, 62, 219, 1, 81, 188, 64 }, { 32, 41, 20, 117, 151, 142, 20, 21, 163 }, { 112, 19, 12, 61, 195, 128, 48, 4, 24 } } }; static int PutI4Mode(VP8BitWriter* const bw, int mode, const uint8_t* const prob) { if (VP8PutBit(bw, mode != B_DC_PRED, prob[0])) { if (VP8PutBit(bw, mode != B_TM_PRED, prob[1])) { if (VP8PutBit(bw, mode != B_VE_PRED, prob[2])) { if (!VP8PutBit(bw, mode >= B_LD_PRED, prob[3])) { if (VP8PutBit(bw, mode != B_HE_PRED, prob[4])) { VP8PutBit(bw, mode != B_RD_PRED, prob[5]); } } else { if (VP8PutBit(bw, mode != B_LD_PRED, prob[6])) { if (VP8PutBit(bw, mode != B_VL_PRED, prob[7])) { VP8PutBit(bw, mode != B_HD_PRED, prob[8]); } } } } } } return mode; } static void PutI16Mode(VP8BitWriter* const bw, int mode) { if (VP8PutBit(bw, (mode == TM_PRED || mode == H_PRED), 156)) { VP8PutBit(bw, mode == TM_PRED, 128); // TM or HE } else { VP8PutBit(bw, mode == V_PRED, 163); // VE or DC } } static void PutUVMode(VP8BitWriter* const bw, int uv_mode) { if (VP8PutBit(bw, uv_mode != DC_PRED, 142)) { if (VP8PutBit(bw, uv_mode != V_PRED, 114)) { VP8PutBit(bw, uv_mode != H_PRED, 183); // else: TM_PRED } } } static void PutSegment(VP8BitWriter* const bw, int s, const uint8_t* p) { if (VP8PutBit(bw, s >= 2, p[0])) p += 1; VP8PutBit(bw, s & 1, p[1]); } void VP8CodeIntraModes(VP8Encoder* const enc) { VP8BitWriter* const bw = &enc->bw_; VP8EncIterator it; VP8IteratorInit(enc, &it); do { const VP8MBInfo* const mb = it.mb_; const uint8_t* preds = it.preds_; if (enc->segment_hdr_.update_map_) { PutSegment(bw, mb->segment_, enc->proba_.segments_); } if (enc->proba_.use_skip_proba_) { VP8PutBit(bw, mb->skip_, enc->proba_.skip_proba_); } if (VP8PutBit(bw, (mb->type_ != 0), 145)) { // i16x16 PutI16Mode(bw, preds[0]); } else { const int preds_w = enc->preds_w_; const uint8_t* top_pred = preds - preds_w; int x, y; for (y = 0; y < 4; ++y) { int left = preds[-1]; for (x = 0; x < 4; ++x) { const uint8_t* const probas = kBModesProba[top_pred[x]][left]; left = PutI4Mode(bw, preds[x], probas); } top_pred = preds; preds += preds_w; } } PutUVMode(bw, mb->uv_mode_); } while (VP8IteratorNext(&it)); } //------------------------------------------------------------------------------ // Paragraph 13 const uint8_t VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = { { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 }, { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 }, { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 } }, { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 }, { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 }, { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 } }, { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 }, { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } } }; void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas) { int t, b, c, p; for (t = 0; t < NUM_TYPES; ++t) { for (b = 0; b < NUM_BANDS; ++b) { for (c = 0; c < NUM_CTX; ++c) { for (p = 0; p < NUM_PROBAS; ++p) { const uint8_t p0 = probas->coeffs_[t][b][c][p]; const int update = (p0 != VP8CoeffsProba0[t][b][c][p]); if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) { VP8PutValue(bw, p0, 8); } } } } } if (VP8PutBitUniform(bw, probas->use_skip_proba_)) { VP8PutValue(bw, probas->skip_proba_, 8); } } libwebp-0.4.0/src/enc/frame.c0000644000014400001440000010203012255002107012627 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // frame coding and analysis // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #include #include "./vp8enci.h" #include "./cost.h" #include "../webp/format_constants.h" // RIFF constants #define SEGMENT_VISU 0 #define DEBUG_SEARCH 0 // useful to track search convergence // On-the-fly info about the current set of residuals. Handy to avoid // passing zillions of params. typedef struct { int first; int last; const int16_t* coeffs; int coeff_type; ProbaArray* prob; StatsArray* stats; CostArray* cost; } VP8Residual; //------------------------------------------------------------------------------ // multi-pass convergence #define HEADER_SIZE_ESTIMATE (RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + \ VP8_FRAME_HEADER_SIZE) #define DQ_LIMIT 0.4 // convergence is considered reached if dq < DQ_LIMIT // we allow 2k of extra head-room in PARTITION0 limit. #define PARTITION0_SIZE_LIMIT ((VP8_MAX_PARTITION0_SIZE - 2048ULL) << 11) typedef struct { // struct for organizing convergence in either size or PSNR int is_first; float dq; float q, last_q; double value, last_value; // PSNR or size double target; int do_size_search; } PassStats; static int InitPassStats(const VP8Encoder* const enc, PassStats* const s) { const uint64_t target_size = (uint64_t)enc->config_->target_size; const int do_size_search = (target_size != 0); const float target_PSNR = enc->config_->target_PSNR; s->is_first = 1; s->dq = 10.f; s->q = s->last_q = enc->config_->quality; s->target = do_size_search ? (double)target_size : (target_PSNR > 0.) ? target_PSNR : 40.; // default, just in case s->value = s->last_value = 0.; s->do_size_search = do_size_search; return do_size_search; } static float Clamp(float v, float min, float max) { return (v < min) ? min : (v > max) ? max : v; } static float ComputeNextQ(PassStats* const s) { float dq; if (s->is_first) { dq = (s->value > s->target) ? -s->dq : s->dq; s->is_first = 0; } else if (s->value != s->last_value) { const double slope = (s->target - s->value) / (s->last_value - s->value); dq = (float)(slope * (s->last_q - s->q)); } else { dq = 0.; // we're done?! } // Limit variable to avoid large swings. s->dq = Clamp(dq, -30.f, 30.f); s->last_q = s->q; s->last_value = s->value; s->q = Clamp(s->q + s->dq, 0.f, 100.f); return s->q; } //------------------------------------------------------------------------------ // Tables for level coding const uint8_t VP8EncBands[16 + 1] = { 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0 // sentinel }; const uint8_t VP8Cat3[] = { 173, 148, 140 }; const uint8_t VP8Cat4[] = { 176, 155, 140, 135 }; const uint8_t VP8Cat5[] = { 180, 157, 141, 134, 130 }; const uint8_t VP8Cat6[] = { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129 }; //------------------------------------------------------------------------------ // Reset the statistics about: number of skips, token proba, level cost,... static void ResetStats(VP8Encoder* const enc) { VP8Proba* const proba = &enc->proba_; VP8CalculateLevelCosts(proba); proba->nb_skip_ = 0; } //------------------------------------------------------------------------------ // Skip decision probability #define SKIP_PROBA_THRESHOLD 250 // value below which using skip_proba is OK. static int CalcSkipProba(uint64_t nb, uint64_t total) { return (int)(total ? (total - nb) * 255 / total : 255); } // Returns the bit-cost for coding the skip probability. static int FinalizeSkipProba(VP8Encoder* const enc) { VP8Proba* const proba = &enc->proba_; const int nb_mbs = enc->mb_w_ * enc->mb_h_; const int nb_events = proba->nb_skip_; int size; proba->skip_proba_ = CalcSkipProba(nb_events, nb_mbs); proba->use_skip_proba_ = (proba->skip_proba_ < SKIP_PROBA_THRESHOLD); size = 256; // 'use_skip_proba' bit if (proba->use_skip_proba_) { size += nb_events * VP8BitCost(1, proba->skip_proba_) + (nb_mbs - nb_events) * VP8BitCost(0, proba->skip_proba_); size += 8 * 256; // cost of signaling the skip_proba_ itself. } return size; } //------------------------------------------------------------------------------ // Recording of token probabilities. static void ResetTokenStats(VP8Encoder* const enc) { VP8Proba* const proba = &enc->proba_; memset(proba->stats_, 0, sizeof(proba->stats_)); } // Record proba context used static int Record(int bit, proba_t* const stats) { proba_t p = *stats; if (p >= 0xffff0000u) { // an overflow is inbound. p = ((p + 1u) >> 1) & 0x7fff7fffu; // -> divide the stats by 2. } // record bit count (lower 16 bits) and increment total count (upper 16 bits). p += 0x00010000u + bit; *stats = p; return bit; } // We keep the table free variant around for reference, in case. #define USE_LEVEL_CODE_TABLE // Simulate block coding, but only record statistics. // Note: no need to record the fixed probas. static int RecordCoeffs(int ctx, const VP8Residual* const res) { int n = res->first; // should be stats[VP8EncBands[n]], but it's equivalent for n=0 or 1 proba_t* s = res->stats[n][ctx]; if (res->last < 0) { Record(0, s + 0); return 0; } while (n <= res->last) { int v; Record(1, s + 0); // order of record doesn't matter while ((v = res->coeffs[n++]) == 0) { Record(0, s + 1); s = res->stats[VP8EncBands[n]][0]; } Record(1, s + 1); if (!Record(2u < (unsigned int)(v + 1), s + 2)) { // v = -1 or 1 s = res->stats[VP8EncBands[n]][1]; } else { v = abs(v); #if !defined(USE_LEVEL_CODE_TABLE) if (!Record(v > 4, s + 3)) { if (Record(v != 2, s + 4)) Record(v == 4, s + 5); } else if (!Record(v > 10, s + 6)) { Record(v > 6, s + 7); } else if (!Record((v >= 3 + (8 << 2)), s + 8)) { Record((v >= 3 + (8 << 1)), s + 9); } else { Record((v >= 3 + (8 << 3)), s + 10); } #else if (v > MAX_VARIABLE_LEVEL) v = MAX_VARIABLE_LEVEL; { const int bits = VP8LevelCodes[v - 1][1]; int pattern = VP8LevelCodes[v - 1][0]; int i; for (i = 0; (pattern >>= 1) != 0; ++i) { const int mask = 2 << i; if (pattern & 1) Record(!!(bits & mask), s + 3 + i); } } #endif s = res->stats[VP8EncBands[n]][2]; } } if (n < 16) Record(0, s + 0); return 1; } // Collect statistics and deduce probabilities for next coding pass. // Return the total bit-cost for coding the probability updates. static int CalcTokenProba(int nb, int total) { assert(nb <= total); return nb ? (255 - nb * 255 / total) : 255; } // Cost of coding 'nb' 1's and 'total-nb' 0's using 'proba' probability. static int BranchCost(int nb, int total, int proba) { return nb * VP8BitCost(1, proba) + (total - nb) * VP8BitCost(0, proba); } static int FinalizeTokenProbas(VP8Proba* const proba) { int has_changed = 0; int size = 0; int t, b, c, p; for (t = 0; t < NUM_TYPES; ++t) { for (b = 0; b < NUM_BANDS; ++b) { for (c = 0; c < NUM_CTX; ++c) { for (p = 0; p < NUM_PROBAS; ++p) { const proba_t stats = proba->stats_[t][b][c][p]; const int nb = (stats >> 0) & 0xffff; const int total = (stats >> 16) & 0xffff; const int update_proba = VP8CoeffsUpdateProba[t][b][c][p]; const int old_p = VP8CoeffsProba0[t][b][c][p]; const int new_p = CalcTokenProba(nb, total); const int old_cost = BranchCost(nb, total, old_p) + VP8BitCost(0, update_proba); const int new_cost = BranchCost(nb, total, new_p) + VP8BitCost(1, update_proba) + 8 * 256; const int use_new_p = (old_cost > new_cost); size += VP8BitCost(use_new_p, update_proba); if (use_new_p) { // only use proba that seem meaningful enough. proba->coeffs_[t][b][c][p] = new_p; has_changed |= (new_p != old_p); size += 8 * 256; } else { proba->coeffs_[t][b][c][p] = old_p; } } } } } proba->dirty_ = has_changed; return size; } //------------------------------------------------------------------------------ // Finalize Segment probability based on the coding tree static int GetProba(int a, int b) { const int total = a + b; return (total == 0) ? 255 // that's the default probability. : (255 * a + total / 2) / total; // rounded proba } static void SetSegmentProbas(VP8Encoder* const enc) { int p[NUM_MB_SEGMENTS] = { 0 }; int n; for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { const VP8MBInfo* const mb = &enc->mb_info_[n]; p[mb->segment_]++; } if (enc->pic_->stats != NULL) { for (n = 0; n < NUM_MB_SEGMENTS; ++n) { enc->pic_->stats->segment_size[n] = p[n]; } } if (enc->segment_hdr_.num_segments_ > 1) { uint8_t* const probas = enc->proba_.segments_; probas[0] = GetProba(p[0] + p[1], p[2] + p[3]); probas[1] = GetProba(p[0], p[1]); probas[2] = GetProba(p[2], p[3]); enc->segment_hdr_.update_map_ = (probas[0] != 255) || (probas[1] != 255) || (probas[2] != 255); enc->segment_hdr_.size_ = p[0] * (VP8BitCost(0, probas[0]) + VP8BitCost(0, probas[1])) + p[1] * (VP8BitCost(0, probas[0]) + VP8BitCost(1, probas[1])) + p[2] * (VP8BitCost(1, probas[0]) + VP8BitCost(0, probas[2])) + p[3] * (VP8BitCost(1, probas[0]) + VP8BitCost(1, probas[2])); } else { enc->segment_hdr_.update_map_ = 0; enc->segment_hdr_.size_ = 0; } } //------------------------------------------------------------------------------ // helper functions for residuals struct VP8Residual. static void InitResidual(int first, int coeff_type, VP8Encoder* const enc, VP8Residual* const res) { res->coeff_type = coeff_type; res->prob = enc->proba_.coeffs_[coeff_type]; res->stats = enc->proba_.stats_[coeff_type]; res->cost = enc->proba_.level_cost_[coeff_type]; res->first = first; } static void SetResidualCoeffs(const int16_t* const coeffs, VP8Residual* const res) { int n; res->last = -1; for (n = 15; n >= res->first; --n) { if (coeffs[n]) { res->last = n; break; } } res->coeffs = coeffs; } //------------------------------------------------------------------------------ // Mode costs static int GetResidualCost(int ctx0, const VP8Residual* const res) { int n = res->first; // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1 int p0 = res->prob[n][ctx0][0]; const uint16_t* t = res->cost[n][ctx0]; int cost; if (res->last < 0) { return VP8BitCost(0, p0); } cost = VP8BitCost(1, p0); for (; n < res->last; ++n) { const int v = abs(res->coeffs[n]); const int b = VP8EncBands[n + 1]; const int ctx = (v >= 2) ? 2 : v; cost += VP8LevelCost(t, v); t = res->cost[b][ctx]; // the masking trick is faster than "if (v) cost += ..." with clang cost += (v ? ~0U : 0) & VP8BitCost(1, res->prob[b][ctx][0]); } // Last coefficient is always non-zero { const int v = abs(res->coeffs[n]); assert(v != 0); cost += VP8LevelCost(t, v); if (n < 15) { const int b = VP8EncBands[n + 1]; const int ctx = (v == 1) ? 1 : 2; const int last_p0 = res->prob[b][ctx][0]; cost += VP8BitCost(0, last_p0); } } return cost; } int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]) { const int x = (it->i4_ & 3), y = (it->i4_ >> 2); VP8Residual res; VP8Encoder* const enc = it->enc_; int R = 0; int ctx; InitResidual(0, 3, enc, &res); ctx = it->top_nz_[x] + it->left_nz_[y]; SetResidualCoeffs(levels, &res); R += GetResidualCost(ctx, &res); return R; } int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd) { VP8Residual res; VP8Encoder* const enc = it->enc_; int x, y; int R = 0; VP8IteratorNzToBytes(it); // re-import the non-zero context // DC InitResidual(0, 1, enc, &res); SetResidualCoeffs(rd->y_dc_levels, &res); R += GetResidualCost(it->top_nz_[8] + it->left_nz_[8], &res); // AC InitResidual(1, 0, enc, &res); for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) { const int ctx = it->top_nz_[x] + it->left_nz_[y]; SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res); R += GetResidualCost(ctx, &res); it->top_nz_[x] = it->left_nz_[y] = (res.last >= 0); } } return R; } int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd) { VP8Residual res; VP8Encoder* const enc = it->enc_; int ch, x, y; int R = 0; VP8IteratorNzToBytes(it); // re-import the non-zero context InitResidual(0, 2, enc, &res); for (ch = 0; ch <= 2; ch += 2) { for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x) { const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y]; SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res); R += GetResidualCost(ctx, &res); it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = (res.last >= 0); } } } return R; } //------------------------------------------------------------------------------ // Coefficient coding static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) { int n = res->first; // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1 const uint8_t* p = res->prob[n][ctx]; if (!VP8PutBit(bw, res->last >= 0, p[0])) { return 0; } while (n < 16) { const int c = res->coeffs[n++]; const int sign = c < 0; int v = sign ? -c : c; if (!VP8PutBit(bw, v != 0, p[1])) { p = res->prob[VP8EncBands[n]][0]; continue; } if (!VP8PutBit(bw, v > 1, p[2])) { p = res->prob[VP8EncBands[n]][1]; } else { if (!VP8PutBit(bw, v > 4, p[3])) { if (VP8PutBit(bw, v != 2, p[4])) VP8PutBit(bw, v == 4, p[5]); } else if (!VP8PutBit(bw, v > 10, p[6])) { if (!VP8PutBit(bw, v > 6, p[7])) { VP8PutBit(bw, v == 6, 159); } else { VP8PutBit(bw, v >= 9, 165); VP8PutBit(bw, !(v & 1), 145); } } else { int mask; const uint8_t* tab; if (v < 3 + (8 << 1)) { // VP8Cat3 (3b) VP8PutBit(bw, 0, p[8]); VP8PutBit(bw, 0, p[9]); v -= 3 + (8 << 0); mask = 1 << 2; tab = VP8Cat3; } else if (v < 3 + (8 << 2)) { // VP8Cat4 (4b) VP8PutBit(bw, 0, p[8]); VP8PutBit(bw, 1, p[9]); v -= 3 + (8 << 1); mask = 1 << 3; tab = VP8Cat4; } else if (v < 3 + (8 << 3)) { // VP8Cat5 (5b) VP8PutBit(bw, 1, p[8]); VP8PutBit(bw, 0, p[10]); v -= 3 + (8 << 2); mask = 1 << 4; tab = VP8Cat5; } else { // VP8Cat6 (11b) VP8PutBit(bw, 1, p[8]); VP8PutBit(bw, 1, p[10]); v -= 3 + (8 << 3); mask = 1 << 10; tab = VP8Cat6; } while (mask) { VP8PutBit(bw, !!(v & mask), *tab++); mask >>= 1; } } p = res->prob[VP8EncBands[n]][2]; } VP8PutBitUniform(bw, sign); if (n == 16 || !VP8PutBit(bw, n <= res->last, p[0])) { return 1; // EOB } } return 1; } static void CodeResiduals(VP8BitWriter* const bw, VP8EncIterator* const it, const VP8ModeScore* const rd) { int x, y, ch; VP8Residual res; uint64_t pos1, pos2, pos3; const int i16 = (it->mb_->type_ == 1); const int segment = it->mb_->segment_; VP8Encoder* const enc = it->enc_; VP8IteratorNzToBytes(it); pos1 = VP8BitWriterPos(bw); if (i16) { InitResidual(0, 1, enc, &res); SetResidualCoeffs(rd->y_dc_levels, &res); it->top_nz_[8] = it->left_nz_[8] = PutCoeffs(bw, it->top_nz_[8] + it->left_nz_[8], &res); InitResidual(1, 0, enc, &res); } else { InitResidual(0, 3, enc, &res); } // luma-AC for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) { const int ctx = it->top_nz_[x] + it->left_nz_[y]; SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res); it->top_nz_[x] = it->left_nz_[y] = PutCoeffs(bw, ctx, &res); } } pos2 = VP8BitWriterPos(bw); // U/V InitResidual(0, 2, enc, &res); for (ch = 0; ch <= 2; ch += 2) { for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x) { const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y]; SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res); it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = PutCoeffs(bw, ctx, &res); } } } pos3 = VP8BitWriterPos(bw); it->luma_bits_ = pos2 - pos1; it->uv_bits_ = pos3 - pos2; it->bit_count_[segment][i16] += it->luma_bits_; it->bit_count_[segment][2] += it->uv_bits_; VP8IteratorBytesToNz(it); } // Same as CodeResiduals, but doesn't actually write anything. // Instead, it just records the event distribution. static void RecordResiduals(VP8EncIterator* const it, const VP8ModeScore* const rd) { int x, y, ch; VP8Residual res; VP8Encoder* const enc = it->enc_; VP8IteratorNzToBytes(it); if (it->mb_->type_ == 1) { // i16x16 InitResidual(0, 1, enc, &res); SetResidualCoeffs(rd->y_dc_levels, &res); it->top_nz_[8] = it->left_nz_[8] = RecordCoeffs(it->top_nz_[8] + it->left_nz_[8], &res); InitResidual(1, 0, enc, &res); } else { InitResidual(0, 3, enc, &res); } // luma-AC for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) { const int ctx = it->top_nz_[x] + it->left_nz_[y]; SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res); it->top_nz_[x] = it->left_nz_[y] = RecordCoeffs(ctx, &res); } } // U/V InitResidual(0, 2, enc, &res); for (ch = 0; ch <= 2; ch += 2) { for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x) { const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y]; SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res); it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = RecordCoeffs(ctx, &res); } } } VP8IteratorBytesToNz(it); } //------------------------------------------------------------------------------ // Token buffer #if !defined(DISABLE_TOKEN_BUFFER) static void RecordTokens(VP8EncIterator* const it, const VP8ModeScore* const rd, VP8TBuffer* const tokens) { int x, y, ch; VP8Residual res; VP8Encoder* const enc = it->enc_; VP8IteratorNzToBytes(it); if (it->mb_->type_ == 1) { // i16x16 const int ctx = it->top_nz_[8] + it->left_nz_[8]; InitResidual(0, 1, enc, &res); SetResidualCoeffs(rd->y_dc_levels, &res); it->top_nz_[8] = it->left_nz_[8] = VP8RecordCoeffTokens(ctx, 1, res.first, res.last, res.coeffs, tokens); RecordCoeffs(ctx, &res); InitResidual(1, 0, enc, &res); } else { InitResidual(0, 3, enc, &res); } // luma-AC for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) { const int ctx = it->top_nz_[x] + it->left_nz_[y]; SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res); it->top_nz_[x] = it->left_nz_[y] = VP8RecordCoeffTokens(ctx, res.coeff_type, res.first, res.last, res.coeffs, tokens); RecordCoeffs(ctx, &res); } } // U/V InitResidual(0, 2, enc, &res); for (ch = 0; ch <= 2; ch += 2) { for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x) { const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y]; SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res); it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = VP8RecordCoeffTokens(ctx, 2, res.first, res.last, res.coeffs, tokens); RecordCoeffs(ctx, &res); } } } VP8IteratorBytesToNz(it); } #endif // !DISABLE_TOKEN_BUFFER //------------------------------------------------------------------------------ // ExtraInfo map / Debug function #if SEGMENT_VISU static void SetBlock(uint8_t* p, int value, int size) { int y; for (y = 0; y < size; ++y) { memset(p, value, size); p += BPS; } } #endif static void ResetSSE(VP8Encoder* const enc) { enc->sse_[0] = 0; enc->sse_[1] = 0; enc->sse_[2] = 0; // Note: enc->sse_[3] is managed by alpha.c enc->sse_count_ = 0; } static void StoreSSE(const VP8EncIterator* const it) { VP8Encoder* const enc = it->enc_; const uint8_t* const in = it->yuv_in_; const uint8_t* const out = it->yuv_out_; // Note: not totally accurate at boundary. And doesn't include in-loop filter. enc->sse_[0] += VP8SSE16x16(in + Y_OFF, out + Y_OFF); enc->sse_[1] += VP8SSE8x8(in + U_OFF, out + U_OFF); enc->sse_[2] += VP8SSE8x8(in + V_OFF, out + V_OFF); enc->sse_count_ += 16 * 16; } static void StoreSideInfo(const VP8EncIterator* const it) { VP8Encoder* const enc = it->enc_; const VP8MBInfo* const mb = it->mb_; WebPPicture* const pic = enc->pic_; if (pic->stats != NULL) { StoreSSE(it); enc->block_count_[0] += (mb->type_ == 0); enc->block_count_[1] += (mb->type_ == 1); enc->block_count_[2] += (mb->skip_ != 0); } if (pic->extra_info != NULL) { uint8_t* const info = &pic->extra_info[it->x_ + it->y_ * enc->mb_w_]; switch (pic->extra_info_type) { case 1: *info = mb->type_; break; case 2: *info = mb->segment_; break; case 3: *info = enc->dqm_[mb->segment_].quant_; break; case 4: *info = (mb->type_ == 1) ? it->preds_[0] : 0xff; break; case 5: *info = mb->uv_mode_; break; case 6: { const int b = (int)((it->luma_bits_ + it->uv_bits_ + 7) >> 3); *info = (b > 255) ? 255 : b; break; } case 7: *info = mb->alpha_; break; default: *info = 0; break; }; } #if SEGMENT_VISU // visualize segments and prediction modes SetBlock(it->yuv_out_ + Y_OFF, mb->segment_ * 64, 16); SetBlock(it->yuv_out_ + U_OFF, it->preds_[0] * 64, 8); SetBlock(it->yuv_out_ + V_OFF, mb->uv_mode_ * 64, 8); #endif } static double GetPSNR(uint64_t mse, uint64_t size) { return (mse > 0 && size > 0) ? 10. * log10(255. * 255. * size / mse) : 99; } //------------------------------------------------------------------------------ // StatLoop(): only collect statistics (number of skips, token usage, ...). // This is used for deciding optimal probabilities. It also modifies the // quantizer value if some target (size, PSNR) was specified. static void SetLoopParams(VP8Encoder* const enc, float q) { // Make sure the quality parameter is inside valid bounds q = Clamp(q, 0.f, 100.f); VP8SetSegmentParams(enc, q); // setup segment quantizations and filters SetSegmentProbas(enc); // compute segment probabilities ResetStats(enc); ResetSSE(enc); } static uint64_t OneStatPass(VP8Encoder* const enc, VP8RDLevel rd_opt, int nb_mbs, int percent_delta, PassStats* const s) { VP8EncIterator it; uint64_t size = 0; uint64_t size_p0 = 0; uint64_t distortion = 0; const uint64_t pixel_count = nb_mbs * 384; VP8IteratorInit(enc, &it); SetLoopParams(enc, s->q); do { VP8ModeScore info; VP8IteratorImport(&it, NULL); if (VP8Decimate(&it, &info, rd_opt)) { // Just record the number of skips and act like skip_proba is not used. enc->proba_.nb_skip_++; } RecordResiduals(&it, &info); size += info.R + info.H; size_p0 += info.H; distortion += info.D; if (percent_delta && !VP8IteratorProgress(&it, percent_delta)) return 0; VP8IteratorSaveBoundary(&it); } while (VP8IteratorNext(&it) && --nb_mbs > 0); size_p0 += enc->segment_hdr_.size_; if (s->do_size_search) { size += FinalizeSkipProba(enc); size += FinalizeTokenProbas(&enc->proba_); size = ((size + size_p0 + 1024) >> 11) + HEADER_SIZE_ESTIMATE; s->value = (double)size; } else { s->value = GetPSNR(distortion, pixel_count); } return size_p0; } static int StatLoop(VP8Encoder* const enc) { const int method = enc->method_; const int do_search = enc->do_search_; const int fast_probe = ((method == 0 || method == 3) && !do_search); int num_pass_left = enc->config_->pass; const int task_percent = 20; const int percent_per_pass = (task_percent + num_pass_left / 2) / num_pass_left; const int final_percent = enc->percent_ + task_percent; const VP8RDLevel rd_opt = (method >= 3 || do_search) ? RD_OPT_BASIC : RD_OPT_NONE; int nb_mbs = enc->mb_w_ * enc->mb_h_; PassStats stats; InitPassStats(enc, &stats); ResetTokenStats(enc); // Fast mode: quick analysis pass over few mbs. Better than nothing. if (fast_probe) { if (method == 3) { // we need more stats for method 3 to be reliable. nb_mbs = (nb_mbs > 200) ? nb_mbs >> 1 : 100; } else { nb_mbs = (nb_mbs > 200) ? nb_mbs >> 2 : 50; } } while (num_pass_left-- > 0) { const int is_last_pass = (fabs(stats.dq) <= DQ_LIMIT) || (num_pass_left == 0) || (enc->max_i4_header_bits_ == 0); const uint64_t size_p0 = OneStatPass(enc, rd_opt, nb_mbs, percent_per_pass, &stats); if (size_p0 == 0) return 0; #if (DEBUG_SEARCH > 0) printf("#%d value:%.1lf -> %.1lf q:%.2f -> %.2f\n", num_pass_left, stats.last_value, stats.value, stats.last_q, stats.q); #endif if (enc->max_i4_header_bits_ > 0 && size_p0 > PARTITION0_SIZE_LIMIT) { ++num_pass_left; enc->max_i4_header_bits_ >>= 1; // strengthen header bit limitation... continue; // ...and start over } if (is_last_pass) { break; } // If no target size: just do several pass without changing 'q' if (do_search) { ComputeNextQ(&stats); if (fabs(stats.dq) <= DQ_LIMIT) break; } } if (!do_search || !stats.do_size_search) { // Need to finalize probas now, since it wasn't done during the search. FinalizeSkipProba(enc); FinalizeTokenProbas(&enc->proba_); } VP8CalculateLevelCosts(&enc->proba_); // finalize costs return WebPReportProgress(enc->pic_, final_percent, &enc->percent_); } //------------------------------------------------------------------------------ // Main loops // static const int kAverageBytesPerMB[8] = { 50, 24, 16, 9, 7, 5, 3, 2 }; static int PreLoopInitialize(VP8Encoder* const enc) { int p; int ok = 1; const int average_bytes_per_MB = kAverageBytesPerMB[enc->base_quant_ >> 4]; const int bytes_per_parts = enc->mb_w_ * enc->mb_h_ * average_bytes_per_MB / enc->num_parts_; // Initialize the bit-writers for (p = 0; ok && p < enc->num_parts_; ++p) { ok = VP8BitWriterInit(enc->parts_ + p, bytes_per_parts); } if (!ok) VP8EncFreeBitWriters(enc); // malloc error occurred return ok; } static int PostLoopFinalize(VP8EncIterator* const it, int ok) { VP8Encoder* const enc = it->enc_; if (ok) { // Finalize the partitions, check for extra errors. int p; for (p = 0; p < enc->num_parts_; ++p) { VP8BitWriterFinish(enc->parts_ + p); ok &= !enc->parts_[p].error_; } } if (ok) { // All good. Finish up. if (enc->pic_->stats != NULL) { // finalize byte counters... int i, s; for (i = 0; i <= 2; ++i) { for (s = 0; s < NUM_MB_SEGMENTS; ++s) { enc->residual_bytes_[i][s] = (int)((it->bit_count_[s][i] + 7) >> 3); } } } VP8AdjustFilterStrength(it); // ...and store filter stats. } else { // Something bad happened -> need to do some memory cleanup. VP8EncFreeBitWriters(enc); } return ok; } //------------------------------------------------------------------------------ // VP8EncLoop(): does the final bitstream coding. static void ResetAfterSkip(VP8EncIterator* const it) { if (it->mb_->type_ == 1) { *it->nz_ = 0; // reset all predictors it->left_nz_[8] = 0; } else { *it->nz_ &= (1 << 24); // preserve the dc_nz bit } } int VP8EncLoop(VP8Encoder* const enc) { VP8EncIterator it; int ok = PreLoopInitialize(enc); if (!ok) return 0; StatLoop(enc); // stats-collection loop VP8IteratorInit(enc, &it); VP8InitFilter(&it); do { VP8ModeScore info; const int dont_use_skip = !enc->proba_.use_skip_proba_; const VP8RDLevel rd_opt = enc->rd_opt_level_; VP8IteratorImport(&it, NULL); // Warning! order is important: first call VP8Decimate() and // *then* decide how to code the skip decision if there's one. if (!VP8Decimate(&it, &info, rd_opt) || dont_use_skip) { CodeResiduals(it.bw_, &it, &info); } else { // reset predictors after a skip ResetAfterSkip(&it); } #ifdef WEBP_EXPERIMENTAL_FEATURES if (enc->use_layer_) { VP8EncCodeLayerBlock(&it); } #endif StoreSideInfo(&it); VP8StoreFilterStats(&it); VP8IteratorExport(&it); ok = VP8IteratorProgress(&it, 20); VP8IteratorSaveBoundary(&it); } while (ok && VP8IteratorNext(&it)); return PostLoopFinalize(&it, ok); } //------------------------------------------------------------------------------ // Single pass using Token Buffer. #if !defined(DISABLE_TOKEN_BUFFER) #define MIN_COUNT 96 // minimum number of macroblocks before updating stats int VP8EncTokenLoop(VP8Encoder* const enc) { // Roughly refresh the proba eight times per pass int max_count = (enc->mb_w_ * enc->mb_h_) >> 3; int num_pass_left = enc->config_->pass; const int do_search = enc->do_search_; VP8EncIterator it; VP8Proba* const proba = &enc->proba_; const VP8RDLevel rd_opt = enc->rd_opt_level_; const uint64_t pixel_count = enc->mb_w_ * enc->mb_h_ * 384; PassStats stats; int ok; InitPassStats(enc, &stats); ok = PreLoopInitialize(enc); if (!ok) return 0; if (max_count < MIN_COUNT) max_count = MIN_COUNT; assert(enc->num_parts_ == 1); assert(enc->use_tokens_); assert(proba->use_skip_proba_ == 0); assert(rd_opt >= RD_OPT_BASIC); // otherwise, token-buffer won't be useful assert(num_pass_left > 0); while (ok && num_pass_left-- > 0) { const int is_last_pass = (fabs(stats.dq) <= DQ_LIMIT) || (num_pass_left == 0) || (enc->max_i4_header_bits_ == 0); uint64_t size_p0 = 0; uint64_t distortion = 0; int cnt = max_count; VP8IteratorInit(enc, &it); SetLoopParams(enc, stats.q); if (is_last_pass) { ResetTokenStats(enc); VP8InitFilter(&it); // don't collect stats until last pass (too costly) } VP8TBufferClear(&enc->tokens_); do { VP8ModeScore info; VP8IteratorImport(&it, NULL); if (--cnt < 0) { FinalizeTokenProbas(proba); VP8CalculateLevelCosts(proba); // refresh cost tables for rd-opt cnt = max_count; } VP8Decimate(&it, &info, rd_opt); RecordTokens(&it, &info, &enc->tokens_); size_p0 += info.H; distortion += info.D; #ifdef WEBP_EXPERIMENTAL_FEATURES if (enc->use_layer_) { VP8EncCodeLayerBlock(&it); } #endif if (is_last_pass) { StoreSideInfo(&it); VP8StoreFilterStats(&it); VP8IteratorExport(&it); ok = VP8IteratorProgress(&it, 20); } VP8IteratorSaveBoundary(&it); } while (ok && VP8IteratorNext(&it)); if (!ok) break; size_p0 += enc->segment_hdr_.size_; if (stats.do_size_search) { uint64_t size = FinalizeTokenProbas(&enc->proba_); size += VP8EstimateTokenSize(&enc->tokens_, (const uint8_t*)proba->coeffs_); size = (size + size_p0 + 1024) >> 11; // -> size in bytes size += HEADER_SIZE_ESTIMATE; stats.value = (double)size; } else { // compute and store PSNR stats.value = GetPSNR(distortion, pixel_count); } #if (DEBUG_SEARCH > 0) printf("#%2d metric:%.1lf -> %.1lf last_q=%.2lf q=%.2lf dq=%.2lf\n", num_pass_left, stats.last_value, stats.value, stats.last_q, stats.q, stats.dq); #endif if (size_p0 > PARTITION0_SIZE_LIMIT) { ++num_pass_left; enc->max_i4_header_bits_ >>= 1; // strengthen header bit limitation... continue; // ...and start over } if (is_last_pass) { break; // done } if (do_search) { ComputeNextQ(&stats); // Adjust q } } if (ok) { if (!stats.do_size_search) { FinalizeTokenProbas(&enc->proba_); } ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0, (const uint8_t*)proba->coeffs_, 1); } ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); return PostLoopFinalize(&it, ok); } #else int VP8EncTokenLoop(VP8Encoder* const enc) { (void)enc; return 0; // we shouldn't be here. } #endif // DISABLE_TOKEN_BUFFER //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/syntax.c0000644000014400001440000003250112255002107013070 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Header syntax writing // // Author: Skal (pascal.massimino@gmail.com) #include #include "../utils/utils.h" #include "../webp/format_constants.h" // RIFF constants #include "../webp/mux_types.h" // ALPHA_FLAG #include "./vp8enci.h" //------------------------------------------------------------------------------ // Helper functions static int IsVP8XNeeded(const VP8Encoder* const enc) { return !!enc->has_alpha_; // Currently the only case when VP8X is needed. // This could change in the future. } static int PutPaddingByte(const WebPPicture* const pic) { const uint8_t pad_byte[1] = { 0 }; return !!pic->writer(pad_byte, 1, pic); } //------------------------------------------------------------------------------ // Writers for header's various pieces (in order of appearance) static WebPEncodingError PutRIFFHeader(const VP8Encoder* const enc, size_t riff_size) { const WebPPicture* const pic = enc->pic_; uint8_t riff[RIFF_HEADER_SIZE] = { 'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P' }; assert(riff_size == (uint32_t)riff_size); PutLE32(riff + TAG_SIZE, (uint32_t)riff_size); if (!pic->writer(riff, sizeof(riff), pic)) { return VP8_ENC_ERROR_BAD_WRITE; } return VP8_ENC_OK; } static WebPEncodingError PutVP8XHeader(const VP8Encoder* const enc) { const WebPPicture* const pic = enc->pic_; uint8_t vp8x[CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE] = { 'V', 'P', '8', 'X' }; uint32_t flags = 0; assert(IsVP8XNeeded(enc)); assert(pic->width >= 1 && pic->height >= 1); assert(pic->width <= MAX_CANVAS_SIZE && pic->height <= MAX_CANVAS_SIZE); if (enc->has_alpha_) { flags |= ALPHA_FLAG; } PutLE32(vp8x + TAG_SIZE, VP8X_CHUNK_SIZE); PutLE32(vp8x + CHUNK_HEADER_SIZE, flags); PutLE24(vp8x + CHUNK_HEADER_SIZE + 4, pic->width - 1); PutLE24(vp8x + CHUNK_HEADER_SIZE + 7, pic->height - 1); if (!pic->writer(vp8x, sizeof(vp8x), pic)) { return VP8_ENC_ERROR_BAD_WRITE; } return VP8_ENC_OK; } static WebPEncodingError PutAlphaChunk(const VP8Encoder* const enc) { const WebPPicture* const pic = enc->pic_; uint8_t alpha_chunk_hdr[CHUNK_HEADER_SIZE] = { 'A', 'L', 'P', 'H' }; assert(enc->has_alpha_); // Alpha chunk header. PutLE32(alpha_chunk_hdr + TAG_SIZE, enc->alpha_data_size_); if (!pic->writer(alpha_chunk_hdr, sizeof(alpha_chunk_hdr), pic)) { return VP8_ENC_ERROR_BAD_WRITE; } // Alpha chunk data. if (!pic->writer(enc->alpha_data_, enc->alpha_data_size_, pic)) { return VP8_ENC_ERROR_BAD_WRITE; } // Padding. if ((enc->alpha_data_size_ & 1) && !PutPaddingByte(pic)) { return VP8_ENC_ERROR_BAD_WRITE; } return VP8_ENC_OK; } static WebPEncodingError PutVP8Header(const WebPPicture* const pic, size_t vp8_size) { uint8_t vp8_chunk_hdr[CHUNK_HEADER_SIZE] = { 'V', 'P', '8', ' ' }; assert(vp8_size == (uint32_t)vp8_size); PutLE32(vp8_chunk_hdr + TAG_SIZE, (uint32_t)vp8_size); if (!pic->writer(vp8_chunk_hdr, sizeof(vp8_chunk_hdr), pic)) { return VP8_ENC_ERROR_BAD_WRITE; } return VP8_ENC_OK; } static WebPEncodingError PutVP8FrameHeader(const WebPPicture* const pic, int profile, size_t size0) { uint8_t vp8_frm_hdr[VP8_FRAME_HEADER_SIZE]; uint32_t bits; if (size0 >= VP8_MAX_PARTITION0_SIZE) { // partition #0 is too big to fit return VP8_ENC_ERROR_PARTITION0_OVERFLOW; } // Paragraph 9.1. bits = 0 // keyframe (1b) | (profile << 1) // profile (3b) | (1 << 4) // visible (1b) | ((uint32_t)size0 << 5); // partition length (19b) vp8_frm_hdr[0] = (bits >> 0) & 0xff; vp8_frm_hdr[1] = (bits >> 8) & 0xff; vp8_frm_hdr[2] = (bits >> 16) & 0xff; // signature vp8_frm_hdr[3] = (VP8_SIGNATURE >> 16) & 0xff; vp8_frm_hdr[4] = (VP8_SIGNATURE >> 8) & 0xff; vp8_frm_hdr[5] = (VP8_SIGNATURE >> 0) & 0xff; // dimensions vp8_frm_hdr[6] = pic->width & 0xff; vp8_frm_hdr[7] = pic->width >> 8; vp8_frm_hdr[8] = pic->height & 0xff; vp8_frm_hdr[9] = pic->height >> 8; if (!pic->writer(vp8_frm_hdr, sizeof(vp8_frm_hdr), pic)) { return VP8_ENC_ERROR_BAD_WRITE; } return VP8_ENC_OK; } // WebP Headers. static int PutWebPHeaders(const VP8Encoder* const enc, size_t size0, size_t vp8_size, size_t riff_size) { WebPPicture* const pic = enc->pic_; WebPEncodingError err = VP8_ENC_OK; // RIFF header. err = PutRIFFHeader(enc, riff_size); if (err != VP8_ENC_OK) goto Error; // VP8X. if (IsVP8XNeeded(enc)) { err = PutVP8XHeader(enc); if (err != VP8_ENC_OK) goto Error; } // Alpha. if (enc->has_alpha_) { err = PutAlphaChunk(enc); if (err != VP8_ENC_OK) goto Error; } // VP8 header. err = PutVP8Header(pic, vp8_size); if (err != VP8_ENC_OK) goto Error; // VP8 frame header. err = PutVP8FrameHeader(pic, enc->profile_, size0); if (err != VP8_ENC_OK) goto Error; // All OK. return 1; // Error. Error: return WebPEncodingSetError(pic, err); } // Segmentation header static void PutSegmentHeader(VP8BitWriter* const bw, const VP8Encoder* const enc) { const VP8SegmentHeader* const hdr = &enc->segment_hdr_; const VP8Proba* const proba = &enc->proba_; if (VP8PutBitUniform(bw, (hdr->num_segments_ > 1))) { // We always 'update' the quant and filter strength values const int update_data = 1; int s; VP8PutBitUniform(bw, hdr->update_map_); if (VP8PutBitUniform(bw, update_data)) { // we always use absolute values, not relative ones VP8PutBitUniform(bw, 1); // (segment_feature_mode = 1. Paragraph 9.3.) for (s = 0; s < NUM_MB_SEGMENTS; ++s) { VP8PutSignedValue(bw, enc->dqm_[s].quant_, 7); } for (s = 0; s < NUM_MB_SEGMENTS; ++s) { VP8PutSignedValue(bw, enc->dqm_[s].fstrength_, 6); } } if (hdr->update_map_) { for (s = 0; s < 3; ++s) { if (VP8PutBitUniform(bw, (proba->segments_[s] != 255u))) { VP8PutValue(bw, proba->segments_[s], 8); } } } } } // Filtering parameters header static void PutFilterHeader(VP8BitWriter* const bw, const VP8FilterHeader* const hdr) { const int use_lf_delta = (hdr->i4x4_lf_delta_ != 0); VP8PutBitUniform(bw, hdr->simple_); VP8PutValue(bw, hdr->level_, 6); VP8PutValue(bw, hdr->sharpness_, 3); if (VP8PutBitUniform(bw, use_lf_delta)) { // '0' is the default value for i4x4_lf_delta_ at frame #0. const int need_update = (hdr->i4x4_lf_delta_ != 0); if (VP8PutBitUniform(bw, need_update)) { // we don't use ref_lf_delta => emit four 0 bits VP8PutValue(bw, 0, 4); // we use mode_lf_delta for i4x4 VP8PutSignedValue(bw, hdr->i4x4_lf_delta_, 6); VP8PutValue(bw, 0, 3); // all others unused } } } // Nominal quantization parameters static void PutQuant(VP8BitWriter* const bw, const VP8Encoder* const enc) { VP8PutValue(bw, enc->base_quant_, 7); VP8PutSignedValue(bw, enc->dq_y1_dc_, 4); VP8PutSignedValue(bw, enc->dq_y2_dc_, 4); VP8PutSignedValue(bw, enc->dq_y2_ac_, 4); VP8PutSignedValue(bw, enc->dq_uv_dc_, 4); VP8PutSignedValue(bw, enc->dq_uv_ac_, 4); } // Partition sizes static int EmitPartitionsSize(const VP8Encoder* const enc, WebPPicture* const pic) { uint8_t buf[3 * (MAX_NUM_PARTITIONS - 1)]; int p; for (p = 0; p < enc->num_parts_ - 1; ++p) { const size_t part_size = VP8BitWriterSize(enc->parts_ + p); if (part_size >= VP8_MAX_PARTITION_SIZE) { return WebPEncodingSetError(pic, VP8_ENC_ERROR_PARTITION_OVERFLOW); } buf[3 * p + 0] = (part_size >> 0) & 0xff; buf[3 * p + 1] = (part_size >> 8) & 0xff; buf[3 * p + 2] = (part_size >> 16) & 0xff; } return p ? pic->writer(buf, 3 * p, pic) : 1; } //------------------------------------------------------------------------------ #ifdef WEBP_EXPERIMENTAL_FEATURES #define KTRAILER_SIZE 8 static int WriteExtensions(VP8Encoder* const enc) { uint8_t buffer[KTRAILER_SIZE]; VP8BitWriter* const bw = &enc->bw_; WebPPicture* const pic = enc->pic_; // Layer (bytes 0..3) PutLE24(buffer + 0, enc->layer_data_size_); buffer[3] = enc->pic_->colorspace & WEBP_CSP_UV_MASK; if (enc->layer_data_size_ > 0) { assert(enc->use_layer_); // append layer data to last partition if (!VP8BitWriterAppend(&enc->parts_[enc->num_parts_ - 1], enc->layer_data_, enc->layer_data_size_)) { return WebPEncodingSetError(pic, VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY); } } buffer[KTRAILER_SIZE - 1] = 0x01; // marker if (!VP8BitWriterAppend(bw, buffer, KTRAILER_SIZE)) { return WebPEncodingSetError(pic, VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY); } return 1; } #endif /* WEBP_EXPERIMENTAL_FEATURES */ //------------------------------------------------------------------------------ static size_t GeneratePartition0(VP8Encoder* const enc) { VP8BitWriter* const bw = &enc->bw_; const int mb_size = enc->mb_w_ * enc->mb_h_; uint64_t pos1, pos2, pos3; #ifdef WEBP_EXPERIMENTAL_FEATURES const int need_extensions = enc->use_layer_; #endif pos1 = VP8BitWriterPos(bw); VP8BitWriterInit(bw, mb_size * 7 / 8); // ~7 bits per macroblock #ifdef WEBP_EXPERIMENTAL_FEATURES VP8PutBitUniform(bw, need_extensions); // extensions #else VP8PutBitUniform(bw, 0); // colorspace #endif VP8PutBitUniform(bw, 0); // clamp type PutSegmentHeader(bw, enc); PutFilterHeader(bw, &enc->filter_hdr_); VP8PutValue(bw, enc->num_parts_ == 8 ? 3 : enc->num_parts_ == 4 ? 2 : enc->num_parts_ == 2 ? 1 : 0, 2); PutQuant(bw, enc); VP8PutBitUniform(bw, 0); // no proba update VP8WriteProbas(bw, &enc->proba_); pos2 = VP8BitWriterPos(bw); VP8CodeIntraModes(enc); VP8BitWriterFinish(bw); #ifdef WEBP_EXPERIMENTAL_FEATURES if (need_extensions && !WriteExtensions(enc)) { return 0; } #endif pos3 = VP8BitWriterPos(bw); if (enc->pic_->stats) { enc->pic_->stats->header_bytes[0] = (int)((pos2 - pos1 + 7) >> 3); enc->pic_->stats->header_bytes[1] = (int)((pos3 - pos2 + 7) >> 3); enc->pic_->stats->alpha_data_size = (int)enc->alpha_data_size_; enc->pic_->stats->layer_data_size = (int)enc->layer_data_size_; } return !bw->error_; } void VP8EncFreeBitWriters(VP8Encoder* const enc) { int p; VP8BitWriterWipeOut(&enc->bw_); for (p = 0; p < enc->num_parts_; ++p) { VP8BitWriterWipeOut(enc->parts_ + p); } } int VP8EncWrite(VP8Encoder* const enc) { WebPPicture* const pic = enc->pic_; VP8BitWriter* const bw = &enc->bw_; const int task_percent = 19; const int percent_per_part = task_percent / enc->num_parts_; const int final_percent = enc->percent_ + task_percent; int ok = 0; size_t vp8_size, pad, riff_size; int p; // Partition #0 with header and partition sizes ok = !!GeneratePartition0(enc); // Compute VP8 size vp8_size = VP8_FRAME_HEADER_SIZE + VP8BitWriterSize(bw) + 3 * (enc->num_parts_ - 1); for (p = 0; p < enc->num_parts_; ++p) { vp8_size += VP8BitWriterSize(enc->parts_ + p); } pad = vp8_size & 1; vp8_size += pad; // Compute RIFF size // At the minimum it is: "WEBPVP8 nnnn" + VP8 data size. riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8_size; if (IsVP8XNeeded(enc)) { // Add size for: VP8X header + data. riff_size += CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE; } if (enc->has_alpha_) { // Add size for: ALPH header + data. const uint32_t padded_alpha_size = enc->alpha_data_size_ + (enc->alpha_data_size_ & 1); riff_size += CHUNK_HEADER_SIZE + padded_alpha_size; } // Sanity check. if (riff_size > 0xfffffffeU) { return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG); } // Emit headers and partition #0 { const uint8_t* const part0 = VP8BitWriterBuf(bw); const size_t size0 = VP8BitWriterSize(bw); ok = ok && PutWebPHeaders(enc, size0, vp8_size, riff_size) && pic->writer(part0, size0, pic) && EmitPartitionsSize(enc, pic); VP8BitWriterWipeOut(bw); // will free the internal buffer. } // Token partitions for (p = 0; p < enc->num_parts_; ++p) { const uint8_t* const buf = VP8BitWriterBuf(enc->parts_ + p); const size_t size = VP8BitWriterSize(enc->parts_ + p); if (size) ok = ok && pic->writer(buf, size, pic); VP8BitWriterWipeOut(enc->parts_ + p); // will free the internal buffer. ok = ok && WebPReportProgress(pic, enc->percent_ + percent_per_part, &enc->percent_); } // Padding byte if (ok && pad) { ok = PutPaddingByte(pic); } enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size); ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_); return ok; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/backward_references.h0000644000014400001440000001102612255002107015525 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) // #ifndef WEBP_ENC_BACKWARD_REFERENCES_H_ #define WEBP_ENC_BACKWARD_REFERENCES_H_ #include #include #include "../webp/types.h" #include "../webp/format_constants.h" #ifdef __cplusplus extern "C" { #endif // The spec allows 11, we use 9 bits to reduce memory consumption in encoding. // Having 9 instead of 11 only removes about 0.25 % of compression density. #define MAX_COLOR_CACHE_BITS 9 // Max ever number of codes we'll use: #define PIX_OR_COPY_CODES_MAX \ (NUM_LITERAL_CODES + NUM_LENGTH_CODES + (1 << MAX_COLOR_CACHE_BITS)) // ----------------------------------------------------------------------------- // PixOrCopy enum Mode { kLiteral, kCacheIdx, kCopy, kNone }; typedef struct { // mode as uint8_t to make the memory layout to be exactly 8 bytes. uint8_t mode; uint16_t len; uint32_t argb_or_distance; } PixOrCopy; static WEBP_INLINE PixOrCopy PixOrCopyCreateCopy(uint32_t distance, uint16_t len) { PixOrCopy retval; retval.mode = kCopy; retval.argb_or_distance = distance; retval.len = len; return retval; } static WEBP_INLINE PixOrCopy PixOrCopyCreateCacheIdx(int idx) { PixOrCopy retval; assert(idx >= 0); assert(idx < (1 << MAX_COLOR_CACHE_BITS)); retval.mode = kCacheIdx; retval.argb_or_distance = idx; retval.len = 1; return retval; } static WEBP_INLINE PixOrCopy PixOrCopyCreateLiteral(uint32_t argb) { PixOrCopy retval; retval.mode = kLiteral; retval.argb_or_distance = argb; retval.len = 1; return retval; } static WEBP_INLINE int PixOrCopyIsLiteral(const PixOrCopy* const p) { return (p->mode == kLiteral); } static WEBP_INLINE int PixOrCopyIsCacheIdx(const PixOrCopy* const p) { return (p->mode == kCacheIdx); } static WEBP_INLINE int PixOrCopyIsCopy(const PixOrCopy* const p) { return (p->mode == kCopy); } static WEBP_INLINE uint32_t PixOrCopyLiteral(const PixOrCopy* const p, int component) { assert(p->mode == kLiteral); return (p->argb_or_distance >> (component * 8)) & 0xff; } static WEBP_INLINE uint32_t PixOrCopyLength(const PixOrCopy* const p) { return p->len; } static WEBP_INLINE uint32_t PixOrCopyArgb(const PixOrCopy* const p) { assert(p->mode == kLiteral); return p->argb_or_distance; } static WEBP_INLINE uint32_t PixOrCopyCacheIdx(const PixOrCopy* const p) { assert(p->mode == kCacheIdx); assert(p->argb_or_distance < (1U << MAX_COLOR_CACHE_BITS)); return p->argb_or_distance; } static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) { assert(p->mode == kCopy); return p->argb_or_distance; } // ----------------------------------------------------------------------------- // VP8LBackwardRefs typedef struct { PixOrCopy* refs; int size; // currently used int max_size; // maximum capacity } VP8LBackwardRefs; // Initialize the object. Must be called first. 'refs' can be NULL. void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs); // Release memory and re-initialize the object. 'refs' can be NULL. void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs); // Allocate 'max_size' references. Returns false in case of memory error. int VP8LBackwardRefsAlloc(VP8LBackwardRefs* const refs, int max_size); // ----------------------------------------------------------------------------- // Main entry points // Evaluates best possible backward references for specified quality. // Further optimize for 2D locality if use_2d_locality flag is set. int VP8LGetBackwardReferences(int width, int height, const uint32_t* const argb, int quality, int cache_bits, int use_2d_locality, VP8LBackwardRefs* const best); // Produce an estimate for a good color cache size for the image. int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb, int xsize, int ysize, int* const best_cache_bits); #ifdef __cplusplus } #endif #endif // WEBP_ENC_BACKWARD_REFERENCES_H_ libwebp-0.4.0/src/enc/vp8l.c0000644000014400001440000011267512255002107012446 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // main entry for the lossless encoder. // // Author: Vikas Arora (vikaas.arora@gmail.com) // #include #include #include #include "./backward_references.h" #include "./vp8enci.h" #include "./vp8li.h" #include "../dsp/lossless.h" #include "../utils/bit_writer.h" #include "../utils/huffman_encode.h" #include "../utils/utils.h" #include "../webp/format_constants.h" #define PALETTE_KEY_RIGHT_SHIFT 22 // Key for 1K buffer. #define MAX_HUFF_IMAGE_SIZE (16 * 1024 * 1024) #define MAX_COLORS_FOR_GRAPH 64 // ----------------------------------------------------------------------------- // Palette static int CompareColors(const void* p1, const void* p2) { const uint32_t a = *(const uint32_t*)p1; const uint32_t b = *(const uint32_t*)p2; assert(a != b); return (a < b) ? -1 : 1; } // If number of colors in the image is less than or equal to MAX_PALETTE_SIZE, // creates a palette and returns true, else returns false. static int AnalyzeAndCreatePalette(const WebPPicture* const pic, uint32_t palette[MAX_PALETTE_SIZE], int* const palette_size) { int i, x, y, key; int num_colors = 0; uint8_t in_use[MAX_PALETTE_SIZE * 4] = { 0 }; uint32_t colors[MAX_PALETTE_SIZE * 4]; static const uint32_t kHashMul = 0x1e35a7bd; const uint32_t* argb = pic->argb; const int width = pic->width; const int height = pic->height; uint32_t last_pix = ~argb[0]; // so we're sure that last_pix != argb[0] for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { if (argb[x] == last_pix) { continue; } last_pix = argb[x]; key = (kHashMul * last_pix) >> PALETTE_KEY_RIGHT_SHIFT; while (1) { if (!in_use[key]) { colors[key] = last_pix; in_use[key] = 1; ++num_colors; if (num_colors > MAX_PALETTE_SIZE) { return 0; } break; } else if (colors[key] == last_pix) { // The color is already there. break; } else { // Some other color sits there. // Do linear conflict resolution. ++key; key &= (MAX_PALETTE_SIZE * 4 - 1); // key mask for 1K buffer. } } } argb += pic->argb_stride; } // TODO(skal): could we reuse in_use[] to speed up EncodePalette()? num_colors = 0; for (i = 0; i < (int)(sizeof(in_use) / sizeof(in_use[0])); ++i) { if (in_use[i]) { palette[num_colors] = colors[i]; ++num_colors; } } qsort(palette, num_colors, sizeof(*palette), CompareColors); *palette_size = num_colors; return 1; } static int AnalyzeEntropy(const uint32_t* argb, int width, int height, int argb_stride, double* const nonpredicted_bits, double* const predicted_bits) { int x, y; const uint32_t* last_line = NULL; uint32_t last_pix = argb[0]; // so we're sure that pix_diff == 0 VP8LHistogram* nonpredicted = NULL; VP8LHistogram* predicted = (VP8LHistogram*)malloc(2 * sizeof(*predicted)); if (predicted == NULL) return 0; nonpredicted = predicted + 1; VP8LHistogramInit(predicted, 0); VP8LHistogramInit(nonpredicted, 0); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { const uint32_t pix = argb[x]; const uint32_t pix_diff = VP8LSubPixels(pix, last_pix); if (pix_diff == 0) continue; if (last_line != NULL && pix == last_line[x]) { continue; } last_pix = pix; { const PixOrCopy pix_token = PixOrCopyCreateLiteral(pix); const PixOrCopy pix_diff_token = PixOrCopyCreateLiteral(pix_diff); VP8LHistogramAddSinglePixOrCopy(nonpredicted, &pix_token); VP8LHistogramAddSinglePixOrCopy(predicted, &pix_diff_token); } } last_line = argb; argb += argb_stride; } *nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted); *predicted_bits = VP8LHistogramEstimateBitsBulk(predicted); free(predicted); return 1; } static int VP8LEncAnalyze(VP8LEncoder* const enc, WebPImageHint image_hint) { const WebPPicture* const pic = enc->pic_; assert(pic != NULL && pic->argb != NULL); enc->use_palette_ = AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_); if (image_hint == WEBP_HINT_GRAPH) { if (enc->use_palette_ && enc->palette_size_ < MAX_COLORS_FOR_GRAPH) { enc->use_palette_ = 0; } } if (!enc->use_palette_) { if (image_hint == WEBP_HINT_PHOTO) { enc->use_predict_ = 1; enc->use_cross_color_ = 1; } else { double non_pred_entropy, pred_entropy; if (!AnalyzeEntropy(pic->argb, pic->width, pic->height, pic->argb_stride, &non_pred_entropy, &pred_entropy)) { return 0; } if (pred_entropy < 0.95 * non_pred_entropy) { enc->use_predict_ = 1; enc->use_cross_color_ = 1; } } } return 1; } static int GetHuffBitLengthsAndCodes( const VP8LHistogramSet* const histogram_image, HuffmanTreeCode* const huffman_codes) { int i, k; int ok = 1; uint64_t total_length_size = 0; uint8_t* mem_buf = NULL; const int histogram_image_size = histogram_image->size; // Iterate over all histograms and get the aggregate number of codes used. for (i = 0; i < histogram_image_size; ++i) { const VP8LHistogram* const histo = histogram_image->histograms[i]; HuffmanTreeCode* const codes = &huffman_codes[5 * i]; for (k = 0; k < 5; ++k) { const int num_symbols = (k == 0) ? VP8LHistogramNumCodes(histo) : (k == 4) ? NUM_DISTANCE_CODES : 256; codes[k].num_symbols = num_symbols; total_length_size += num_symbols; } } // Allocate and Set Huffman codes. { uint16_t* codes; uint8_t* lengths; mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size, sizeof(*lengths) + sizeof(*codes)); if (mem_buf == NULL) { ok = 0; goto End; } codes = (uint16_t*)mem_buf; lengths = (uint8_t*)&codes[total_length_size]; for (i = 0; i < 5 * histogram_image_size; ++i) { const int bit_length = huffman_codes[i].num_symbols; huffman_codes[i].codes = codes; huffman_codes[i].code_lengths = lengths; codes += bit_length; lengths += bit_length; } } // Create Huffman trees. for (i = 0; ok && (i < histogram_image_size); ++i) { HuffmanTreeCode* const codes = &huffman_codes[5 * i]; VP8LHistogram* const histo = histogram_image->histograms[i]; ok = ok && VP8LCreateHuffmanTree(histo->literal_, 15, codes + 0); ok = ok && VP8LCreateHuffmanTree(histo->red_, 15, codes + 1); ok = ok && VP8LCreateHuffmanTree(histo->blue_, 15, codes + 2); ok = ok && VP8LCreateHuffmanTree(histo->alpha_, 15, codes + 3); ok = ok && VP8LCreateHuffmanTree(histo->distance_, 15, codes + 4); } End: if (!ok) { free(mem_buf); // If one VP8LCreateHuffmanTree() above fails, we need to clean up behind. memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes)); } return ok; } static void StoreHuffmanTreeOfHuffmanTreeToBitMask( VP8LBitWriter* const bw, const uint8_t* code_length_bitdepth) { // RFC 1951 will calm you down if you are worried about this funny sequence. // This sequence is tuned from that, but more weighted for lower symbol count, // and more spiking histograms. static const uint8_t kStorageOrder[CODE_LENGTH_CODES] = { 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; int i; // Throw away trailing zeros: int codes_to_store = CODE_LENGTH_CODES; for (; codes_to_store > 4; --codes_to_store) { if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) { break; } } VP8LWriteBits(bw, 4, codes_to_store - 4); for (i = 0; i < codes_to_store; ++i) { VP8LWriteBits(bw, 3, code_length_bitdepth[kStorageOrder[i]]); } } static void ClearHuffmanTreeIfOnlyOneSymbol( HuffmanTreeCode* const huffman_code) { int k; int count = 0; for (k = 0; k < huffman_code->num_symbols; ++k) { if (huffman_code->code_lengths[k] != 0) { ++count; if (count > 1) return; } } for (k = 0; k < huffman_code->num_symbols; ++k) { huffman_code->code_lengths[k] = 0; huffman_code->codes[k] = 0; } } static void StoreHuffmanTreeToBitMask( VP8LBitWriter* const bw, const HuffmanTreeToken* const tokens, const int num_tokens, const HuffmanTreeCode* const huffman_code) { int i; for (i = 0; i < num_tokens; ++i) { const int ix = tokens[i].code; const int extra_bits = tokens[i].extra_bits; VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]); switch (ix) { case 16: VP8LWriteBits(bw, 2, extra_bits); break; case 17: VP8LWriteBits(bw, 3, extra_bits); break; case 18: VP8LWriteBits(bw, 7, extra_bits); break; } } } static int StoreFullHuffmanCode(VP8LBitWriter* const bw, const HuffmanTreeCode* const tree) { int ok = 0; uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 }; uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 }; const int max_tokens = tree->num_symbols; int num_tokens; HuffmanTreeCode huffman_code; HuffmanTreeToken* const tokens = (HuffmanTreeToken*)WebPSafeMalloc((uint64_t)max_tokens, sizeof(*tokens)); if (tokens == NULL) return 0; huffman_code.num_symbols = CODE_LENGTH_CODES; huffman_code.code_lengths = code_length_bitdepth; huffman_code.codes = code_length_bitdepth_symbols; VP8LWriteBits(bw, 1, 0); num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens); { int histogram[CODE_LENGTH_CODES] = { 0 }; int i; for (i = 0; i < num_tokens; ++i) { ++histogram[tokens[i].code]; } if (!VP8LCreateHuffmanTree(histogram, 7, &huffman_code)) { goto End; } } StoreHuffmanTreeOfHuffmanTreeToBitMask(bw, code_length_bitdepth); ClearHuffmanTreeIfOnlyOneSymbol(&huffman_code); { int trailing_zero_bits = 0; int trimmed_length = num_tokens; int write_trimmed_length; int length; int i = num_tokens; while (i-- > 0) { const int ix = tokens[i].code; if (ix == 0 || ix == 17 || ix == 18) { --trimmed_length; // discount trailing zeros trailing_zero_bits += code_length_bitdepth[ix]; if (ix == 17) { trailing_zero_bits += 3; } else if (ix == 18) { trailing_zero_bits += 7; } } else { break; } } write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12); length = write_trimmed_length ? trimmed_length : num_tokens; VP8LWriteBits(bw, 1, write_trimmed_length); if (write_trimmed_length) { const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1); const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2; VP8LWriteBits(bw, 3, nbitpairs - 1); assert(trimmed_length >= 2); VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2); } StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code); } ok = 1; End: free(tokens); return ok; } static int StoreHuffmanCode(VP8LBitWriter* const bw, const HuffmanTreeCode* const huffman_code) { int i; int count = 0; int symbols[2] = { 0, 0 }; const int kMaxBits = 8; const int kMaxSymbol = 1 << kMaxBits; // Check whether it's a small tree. for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) { if (huffman_code->code_lengths[i] != 0) { if (count < 2) symbols[count] = i; ++count; } } if (count == 0) { // emit minimal tree for empty cases // bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0 VP8LWriteBits(bw, 4, 0x01); return 1; } else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) { VP8LWriteBits(bw, 1, 1); // Small tree marker to encode 1 or 2 symbols. VP8LWriteBits(bw, 1, count - 1); if (symbols[0] <= 1) { VP8LWriteBits(bw, 1, 0); // Code bit for small (1 bit) symbol value. VP8LWriteBits(bw, 1, symbols[0]); } else { VP8LWriteBits(bw, 1, 1); VP8LWriteBits(bw, 8, symbols[0]); } if (count == 2) { VP8LWriteBits(bw, 8, symbols[1]); } return 1; } else { return StoreFullHuffmanCode(bw, huffman_code); } } static void WriteHuffmanCode(VP8LBitWriter* const bw, const HuffmanTreeCode* const code, int code_index) { const int depth = code->code_lengths[code_index]; const int symbol = code->codes[code_index]; VP8LWriteBits(bw, depth, symbol); } static void StoreImageToBitMask( VP8LBitWriter* const bw, int width, int histo_bits, const VP8LBackwardRefs* const refs, const uint16_t* histogram_symbols, const HuffmanTreeCode* const huffman_codes) { // x and y trace the position in the image. int x = 0; int y = 0; const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1; int i; for (i = 0; i < refs->size; ++i) { const PixOrCopy* const v = &refs->refs[i]; const int histogram_ix = histogram_symbols[histo_bits ? (y >> histo_bits) * histo_xsize + (x >> histo_bits) : 0]; const HuffmanTreeCode* const codes = huffman_codes + 5 * histogram_ix; if (PixOrCopyIsCacheIdx(v)) { const int code = PixOrCopyCacheIdx(v); const int literal_ix = 256 + NUM_LENGTH_CODES + code; WriteHuffmanCode(bw, codes, literal_ix); } else if (PixOrCopyIsLiteral(v)) { static const int order[] = { 1, 2, 0, 3 }; int k; for (k = 0; k < 4; ++k) { const int code = PixOrCopyLiteral(v, order[k]); WriteHuffmanCode(bw, codes + k, code); } } else { int bits, n_bits; int code, distance; VP8LPrefixEncode(v->len, &code, &n_bits, &bits); WriteHuffmanCode(bw, codes, 256 + code); VP8LWriteBits(bw, n_bits, bits); distance = PixOrCopyDistance(v); VP8LPrefixEncode(distance, &code, &n_bits, &bits); WriteHuffmanCode(bw, codes + 4, code); VP8LWriteBits(bw, n_bits, bits); } x += PixOrCopyLength(v); while (x >= width) { x -= width; ++y; } } } // Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31 static int EncodeImageNoHuffman(VP8LBitWriter* const bw, const uint32_t* const argb, int width, int height, int quality) { int i; int ok = 0; VP8LBackwardRefs refs; HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } }; const uint16_t histogram_symbols[1] = { 0 }; // only one tree, one symbol VP8LHistogramSet* const histogram_image = VP8LAllocateHistogramSet(1, 0); if (histogram_image == NULL) return 0; // Calculate backward references from ARGB image. if (!VP8LGetBackwardReferences(width, height, argb, quality, 0, 1, &refs)) { goto Error; } // Build histogram image and symbols from backward references. VP8LHistogramStoreRefs(&refs, histogram_image->histograms[0]); // Create Huffman bit lengths and codes for each histogram image. assert(histogram_image->size == 1); if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) { goto Error; } // No color cache, no Huffman image. VP8LWriteBits(bw, 1, 0); // Store Huffman codes. for (i = 0; i < 5; ++i) { HuffmanTreeCode* const codes = &huffman_codes[i]; if (!StoreHuffmanCode(bw, codes)) { goto Error; } ClearHuffmanTreeIfOnlyOneSymbol(codes); } // Store actual literals. StoreImageToBitMask(bw, width, 0, &refs, histogram_symbols, huffman_codes); ok = 1; Error: free(histogram_image); VP8LClearBackwardRefs(&refs); free(huffman_codes[0].codes); return ok; } static int EncodeImageInternal(VP8LBitWriter* const bw, const uint32_t* const argb, int width, int height, int quality, int cache_bits, int histogram_bits) { int ok = 0; const int use_2d_locality = 1; const int use_color_cache = (cache_bits > 0); const uint32_t histogram_image_xysize = VP8LSubSampleSize(width, histogram_bits) * VP8LSubSampleSize(height, histogram_bits); VP8LHistogramSet* histogram_image = VP8LAllocateHistogramSet(histogram_image_xysize, 0); int histogram_image_size = 0; size_t bit_array_size = 0; HuffmanTreeCode* huffman_codes = NULL; VP8LBackwardRefs refs; uint16_t* const histogram_symbols = (uint16_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize, sizeof(*histogram_symbols)); assert(histogram_bits >= MIN_HUFFMAN_BITS); assert(histogram_bits <= MAX_HUFFMAN_BITS); if (histogram_image == NULL || histogram_symbols == NULL) { free(histogram_image); free(histogram_symbols); return 0; } // Calculate backward references from ARGB image. if (!VP8LGetBackwardReferences(width, height, argb, quality, cache_bits, use_2d_locality, &refs)) { goto Error; } // Build histogram image and symbols from backward references. if (!VP8LGetHistoImageSymbols(width, height, &refs, quality, histogram_bits, cache_bits, histogram_image, histogram_symbols)) { goto Error; } // Create Huffman bit lengths and codes for each histogram image. histogram_image_size = histogram_image->size; bit_array_size = 5 * histogram_image_size; huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size, sizeof(*huffman_codes)); if (huffman_codes == NULL || !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) { goto Error; } // Free combined histograms. free(histogram_image); histogram_image = NULL; // Color Cache parameters. VP8LWriteBits(bw, 1, use_color_cache); if (use_color_cache) { VP8LWriteBits(bw, 4, cache_bits); } // Huffman image + meta huffman. { const int write_histogram_image = (histogram_image_size > 1); VP8LWriteBits(bw, 1, write_histogram_image); if (write_histogram_image) { uint32_t* const histogram_argb = (uint32_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize, sizeof(*histogram_argb)); int max_index = 0; uint32_t i; if (histogram_argb == NULL) goto Error; for (i = 0; i < histogram_image_xysize; ++i) { const int symbol_index = histogram_symbols[i] & 0xffff; histogram_argb[i] = 0xff000000 | (symbol_index << 8); if (symbol_index >= max_index) { max_index = symbol_index + 1; } } histogram_image_size = max_index; VP8LWriteBits(bw, 3, histogram_bits - 2); ok = EncodeImageNoHuffman(bw, histogram_argb, VP8LSubSampleSize(width, histogram_bits), VP8LSubSampleSize(height, histogram_bits), quality); free(histogram_argb); if (!ok) goto Error; } } // Store Huffman codes. { int i; for (i = 0; i < 5 * histogram_image_size; ++i) { HuffmanTreeCode* const codes = &huffman_codes[i]; if (!StoreHuffmanCode(bw, codes)) goto Error; ClearHuffmanTreeIfOnlyOneSymbol(codes); } } // Store actual literals. StoreImageToBitMask(bw, width, histogram_bits, &refs, histogram_symbols, huffman_codes); ok = 1; Error: free(histogram_image); VP8LClearBackwardRefs(&refs); if (huffman_codes != NULL) { free(huffman_codes->codes); free(huffman_codes); } free(histogram_symbols); return ok; } // ----------------------------------------------------------------------------- // Transforms // Check if it would be a good idea to subtract green from red and blue. We // only impact entropy in red/blue components, don't bother to look at others. static int EvalAndApplySubtractGreen(VP8LEncoder* const enc, int width, int height, VP8LBitWriter* const bw) { if (!enc->use_palette_) { int i; const uint32_t* const argb = enc->argb_; double bit_cost_before, bit_cost_after; VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo)); if (histo == NULL) return 0; VP8LHistogramInit(histo, 1); for (i = 0; i < width * height; ++i) { const uint32_t c = argb[i]; ++histo->red_[(c >> 16) & 0xff]; ++histo->blue_[(c >> 0) & 0xff]; } bit_cost_before = VP8LHistogramEstimateBits(histo); VP8LHistogramInit(histo, 1); for (i = 0; i < width * height; ++i) { const uint32_t c = argb[i]; const int green = (c >> 8) & 0xff; ++histo->red_[((c >> 16) - green) & 0xff]; ++histo->blue_[((c >> 0) - green) & 0xff]; } bit_cost_after = VP8LHistogramEstimateBits(histo); free(histo); // Check if subtracting green yields low entropy. enc->use_subtract_green_ = (bit_cost_after < bit_cost_before); if (enc->use_subtract_green_) { VP8LWriteBits(bw, 1, TRANSFORM_PRESENT); VP8LWriteBits(bw, 2, SUBTRACT_GREEN); VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height); } } return 1; } static int ApplyPredictFilter(const VP8LEncoder* const enc, int width, int height, int quality, VP8LBitWriter* const bw) { const int pred_bits = enc->transform_bits_; const int transform_width = VP8LSubSampleSize(width, pred_bits); const int transform_height = VP8LSubSampleSize(height, pred_bits); VP8LResidualImage(width, height, pred_bits, enc->argb_, enc->argb_scratch_, enc->transform_data_); VP8LWriteBits(bw, 1, TRANSFORM_PRESENT); VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM); assert(pred_bits >= 2); VP8LWriteBits(bw, 3, pred_bits - 2); if (!EncodeImageNoHuffman(bw, enc->transform_data_, transform_width, transform_height, quality)) { return 0; } return 1; } static int ApplyCrossColorFilter(const VP8LEncoder* const enc, int width, int height, int quality, VP8LBitWriter* const bw) { const int ccolor_transform_bits = enc->transform_bits_; const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits); const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits); const int step = (quality < 25) ? 32 : (quality > 50) ? 8 : 16; VP8LColorSpaceTransform(width, height, ccolor_transform_bits, step, enc->argb_, enc->transform_data_); VP8LWriteBits(bw, 1, TRANSFORM_PRESENT); VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM); assert(ccolor_transform_bits >= 2); VP8LWriteBits(bw, 3, ccolor_transform_bits - 2); if (!EncodeImageNoHuffman(bw, enc->transform_data_, transform_width, transform_height, quality)) { return 0; } return 1; } // ----------------------------------------------------------------------------- static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic, size_t riff_size, size_t vp8l_size) { uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = { 'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P', 'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE, }; PutLE32(riff + TAG_SIZE, (uint32_t)riff_size); PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size); if (!pic->writer(riff, sizeof(riff), pic)) { return VP8_ENC_ERROR_BAD_WRITE; } return VP8_ENC_OK; } static int WriteImageSize(const WebPPicture* const pic, VP8LBitWriter* const bw) { const int width = pic->width - 1; const int height = pic->height - 1; assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION); VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, width); VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, height); return !bw->error_; } static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) { VP8LWriteBits(bw, 1, has_alpha); VP8LWriteBits(bw, VP8L_VERSION_BITS, VP8L_VERSION); return !bw->error_; } static WebPEncodingError WriteImage(const WebPPicture* const pic, VP8LBitWriter* const bw, size_t* const coded_size) { WebPEncodingError err = VP8_ENC_OK; const uint8_t* const webpll_data = VP8LBitWriterFinish(bw); const size_t webpll_size = VP8LBitWriterNumBytes(bw); const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size; const size_t pad = vp8l_size & 1; const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad; err = WriteRiffHeader(pic, riff_size, vp8l_size); if (err != VP8_ENC_OK) goto Error; if (!pic->writer(webpll_data, webpll_size, pic)) { err = VP8_ENC_ERROR_BAD_WRITE; goto Error; } if (pad) { const uint8_t pad_byte[1] = { 0 }; if (!pic->writer(pad_byte, 1, pic)) { err = VP8_ENC_ERROR_BAD_WRITE; goto Error; } } *coded_size = CHUNK_HEADER_SIZE + riff_size; return VP8_ENC_OK; Error: return err; } // ----------------------------------------------------------------------------- // Allocates the memory for argb (W x H) buffer, 2 rows of context for // prediction and transform data. static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc, int width, int height) { WebPEncodingError err = VP8_ENC_OK; const int tile_size = 1 << enc->transform_bits_; const uint64_t image_size = width * height; const uint64_t argb_scratch_size = tile_size * width + width; const uint64_t transform_data_size = (uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) * (uint64_t)VP8LSubSampleSize(height, enc->transform_bits_); const uint64_t total_size = image_size + argb_scratch_size + transform_data_size; uint32_t* mem = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*mem)); if (mem == NULL) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } enc->argb_ = mem; mem += image_size; enc->argb_scratch_ = mem; mem += argb_scratch_size; enc->transform_data_ = mem; enc->current_width_ = width; Error: return err; } static void ApplyPalette(uint32_t* src, uint32_t* dst, uint32_t src_stride, uint32_t dst_stride, const uint32_t* palette, int palette_size, int width, int height, int xbits, uint8_t* row) { int i, x, y; int use_LUT = 1; for (i = 0; i < palette_size; ++i) { if ((palette[i] & 0xffff00ffu) != 0) { use_LUT = 0; break; } } if (use_LUT) { uint8_t inv_palette[MAX_PALETTE_SIZE] = { 0 }; for (i = 0; i < palette_size; ++i) { const int color = (palette[i] >> 8) & 0xff; inv_palette[color] = i; } for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { const int color = (src[x] >> 8) & 0xff; row[x] = inv_palette[color]; } VP8LBundleColorMap(row, width, xbits, dst); src += src_stride; dst += dst_stride; } } else { // Use 1 pixel cache for ARGB pixels. uint32_t last_pix = palette[0]; int last_idx = 0; for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { const uint32_t pix = src[x]; if (pix != last_pix) { for (i = 0; i < palette_size; ++i) { if (pix == palette[i]) { last_idx = i; last_pix = pix; break; } } } row[x] = last_idx; } VP8LBundleColorMap(row, width, xbits, dst); src += src_stride; dst += dst_stride; } } } // Note: Expects "enc->palette_" to be set properly. // Also, "enc->palette_" will be modified after this call and should not be used // later. static WebPEncodingError EncodePalette(VP8LBitWriter* const bw, VP8LEncoder* const enc, int quality) { WebPEncodingError err = VP8_ENC_OK; int i; const WebPPicture* const pic = enc->pic_; uint32_t* src = pic->argb; uint32_t* dst; const int width = pic->width; const int height = pic->height; uint32_t* const palette = enc->palette_; const int palette_size = enc->palette_size_; uint8_t* row = NULL; int xbits; // Replace each input pixel by corresponding palette index. // This is done line by line. if (palette_size <= 4) { xbits = (palette_size <= 2) ? 3 : 2; } else { xbits = (palette_size <= 16) ? 1 : 0; } err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height); if (err != VP8_ENC_OK) goto Error; dst = enc->argb_; row = (uint8_t*)WebPSafeMalloc((uint64_t)width, sizeof(*row)); if (row == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY; ApplyPalette(src, dst, pic->argb_stride, enc->current_width_, palette, palette_size, width, height, xbits, row); // Save palette to bitstream. VP8LWriteBits(bw, 1, TRANSFORM_PRESENT); VP8LWriteBits(bw, 2, COLOR_INDEXING_TRANSFORM); assert(palette_size >= 1); VP8LWriteBits(bw, 8, palette_size - 1); for (i = palette_size - 1; i >= 1; --i) { palette[i] = VP8LSubPixels(palette[i], palette[i - 1]); } if (!EncodeImageNoHuffman(bw, palette, palette_size, 1, quality)) { err = VP8_ENC_ERROR_INVALID_CONFIGURATION; goto Error; } Error: free(row); return err; } // ----------------------------------------------------------------------------- static int GetHistoBits(int method, int use_palette, int width, int height) { const uint64_t hist_size = sizeof(VP8LHistogram); // Make tile size a function of encoding method (Range: 0 to 6). int histo_bits = (use_palette ? 9 : 7) - method; while (1) { const uint64_t huff_image_size = VP8LSubSampleSize(width, histo_bits) * VP8LSubSampleSize(height, histo_bits) * hist_size; if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break; ++histo_bits; } return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS : (histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits; } static void FinishEncParams(VP8LEncoder* const enc) { const WebPConfig* const config = enc->config_; const WebPPicture* const pic = enc->pic_; const int method = config->method; const float quality = config->quality; const int use_palette = enc->use_palette_; enc->transform_bits_ = (method < 4) ? 5 : (method > 4) ? 3 : 4; enc->histo_bits_ = GetHistoBits(method, use_palette, pic->width, pic->height); enc->cache_bits_ = (quality <= 25.f) ? 0 : 7; } // ----------------------------------------------------------------------------- // VP8LEncoder static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config, const WebPPicture* const picture) { VP8LEncoder* const enc = (VP8LEncoder*)calloc(1, sizeof(*enc)); if (enc == NULL) { WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); return NULL; } enc->config_ = config; enc->pic_ = picture; VP8LDspInit(); return enc; } static void VP8LEncoderDelete(VP8LEncoder* enc) { free(enc->argb_); free(enc); } // ----------------------------------------------------------------------------- // Main call WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, const WebPPicture* const picture, VP8LBitWriter* const bw) { WebPEncodingError err = VP8_ENC_OK; const int quality = (int)config->quality; const int width = picture->width; const int height = picture->height; VP8LEncoder* const enc = VP8LEncoderNew(config, picture); const size_t byte_position = VP8LBitWriterNumBytes(bw); if (enc == NULL) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } // --------------------------------------------------------------------------- // Analyze image (entropy, num_palettes etc) if (!VP8LEncAnalyze(enc, config->image_hint)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } FinishEncParams(enc); if (enc->use_palette_) { err = EncodePalette(bw, enc, quality); if (err != VP8_ENC_OK) goto Error; // Color cache is disabled for palette. enc->cache_bits_ = 0; } // In case image is not packed. if (enc->argb_ == NULL) { int y; err = AllocateTransformBuffer(enc, width, height); if (err != VP8_ENC_OK) goto Error; for (y = 0; y < height; ++y) { memcpy(enc->argb_ + y * width, picture->argb + y * picture->argb_stride, width * sizeof(*enc->argb_)); } enc->current_width_ = width; } // --------------------------------------------------------------------------- // Apply transforms and write transform data. if (!EvalAndApplySubtractGreen(enc, enc->current_width_, height, bw)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } if (enc->use_predict_) { if (!ApplyPredictFilter(enc, enc->current_width_, height, quality, bw)) { err = VP8_ENC_ERROR_INVALID_CONFIGURATION; goto Error; } } if (enc->use_cross_color_) { if (!ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw)) { err = VP8_ENC_ERROR_INVALID_CONFIGURATION; goto Error; } } VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT); // No more transforms. // --------------------------------------------------------------------------- // Estimate the color cache size. if (enc->cache_bits_ > 0) { if (!VP8LCalculateEstimateForCacheSize(enc->argb_, enc->current_width_, height, &enc->cache_bits_)) { err = VP8_ENC_ERROR_INVALID_CONFIGURATION; goto Error; } } // --------------------------------------------------------------------------- // Encode and write the transformed image. if (!EncodeImageInternal(bw, enc->argb_, enc->current_width_, height, quality, enc->cache_bits_, enc->histo_bits_)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } if (picture->stats != NULL) { WebPAuxStats* const stats = picture->stats; stats->lossless_features = 0; if (enc->use_predict_) stats->lossless_features |= 1; if (enc->use_cross_color_) stats->lossless_features |= 2; if (enc->use_subtract_green_) stats->lossless_features |= 4; if (enc->use_palette_) stats->lossless_features |= 8; stats->histogram_bits = enc->histo_bits_; stats->transform_bits = enc->transform_bits_; stats->cache_bits = enc->cache_bits_; stats->palette_size = enc->palette_size_; stats->lossless_size = (int)(VP8LBitWriterNumBytes(bw) - byte_position); } Error: VP8LEncoderDelete(enc); return err; } int VP8LEncodeImage(const WebPConfig* const config, const WebPPicture* const picture) { int width, height; int has_alpha; size_t coded_size; int percent = 0; WebPEncodingError err = VP8_ENC_OK; VP8LBitWriter bw; if (picture == NULL) return 0; if (config == NULL || picture->argb == NULL) { err = VP8_ENC_ERROR_NULL_PARAMETER; WebPEncodingSetError(picture, err); return 0; } width = picture->width; height = picture->height; if (!VP8LBitWriterInit(&bw, (width * height) >> 1)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } if (!WebPReportProgress(picture, 1, &percent)) { UserAbort: err = VP8_ENC_ERROR_USER_ABORT; goto Error; } // Reset stats (for pure lossless coding) if (picture->stats != NULL) { WebPAuxStats* const stats = picture->stats; memset(stats, 0, sizeof(*stats)); stats->PSNR[0] = 99.f; stats->PSNR[1] = 99.f; stats->PSNR[2] = 99.f; stats->PSNR[3] = 99.f; stats->PSNR[4] = 99.f; } // Write image size. if (!WriteImageSize(picture, &bw)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } has_alpha = WebPPictureHasTransparency(picture); // Write the non-trivial Alpha flag and lossless version. if (!WriteRealAlphaAndVersion(&bw, has_alpha)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort; // Encode main image stream. err = VP8LEncodeStream(config, picture, &bw); if (err != VP8_ENC_OK) goto Error; // TODO(skal): have a fine-grained progress report in VP8LEncodeStream(). if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort; // Finish the RIFF chunk. err = WriteImage(picture, &bw, &coded_size); if (err != VP8_ENC_OK) goto Error; if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort; // Save size. if (picture->stats != NULL) { picture->stats->coded_size += (int)coded_size; picture->stats->lossless_size = (int)coded_size; } if (picture->extra_info != NULL) { const int mb_w = (width + 15) >> 4; const int mb_h = (height + 15) >> 4; memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info)); } Error: if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY; VP8LBitWriterDestroy(&bw); if (err != VP8_ENC_OK) { WebPEncodingSetError(picture, err); return 0; } return 1; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/picture.c0000644000014400001440000012713512255002107013225 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // WebPPicture utils: colorspace conversion, crop, ... // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #include "./vp8enci.h" #include "../utils/alpha_processing.h" #include "../utils/random.h" #include "../utils/rescaler.h" #include "../utils/utils.h" #include "../dsp/dsp.h" #include "../dsp/yuv.h" // Uncomment to disable gamma-compression during RGB->U/V averaging #define USE_GAMMA_COMPRESSION #define HALVE(x) (((x) + 1) >> 1) #define IS_YUV_CSP(csp, YUV_CSP) (((csp) & WEBP_CSP_UV_MASK) == (YUV_CSP)) static const union { uint32_t argb; uint8_t bytes[4]; } test_endian = { 0xff000000u }; #define ALPHA_IS_LAST (test_endian.bytes[3] == 0xff) static WEBP_INLINE uint32_t MakeARGB32(int r, int g, int b) { return (0xff000000u | (r << 16) | (g << 8) | b); } //------------------------------------------------------------------------------ // WebPPicture //------------------------------------------------------------------------------ int WebPPictureAlloc(WebPPicture* picture) { if (picture != NULL) { const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK; const int has_alpha = picture->colorspace & WEBP_CSP_ALPHA_BIT; const int width = picture->width; const int height = picture->height; if (!picture->use_argb) { const int y_stride = width; const int uv_width = HALVE(width); const int uv_height = HALVE(height); const int uv_stride = uv_width; int uv0_stride = 0; int a_width, a_stride; uint64_t y_size, uv_size, uv0_size, a_size, total_size; uint8_t* mem; // U/V switch (uv_csp) { case WEBP_YUV420: break; #ifdef WEBP_EXPERIMENTAL_FEATURES case WEBP_YUV400: // for now, we'll just reset the U/V samples break; case WEBP_YUV422: uv0_stride = uv_width; break; case WEBP_YUV444: uv0_stride = width; break; #endif default: return 0; } uv0_size = height * uv0_stride; // alpha a_width = has_alpha ? width : 0; a_stride = a_width; y_size = (uint64_t)y_stride * height; uv_size = (uint64_t)uv_stride * uv_height; a_size = (uint64_t)a_stride * height; total_size = y_size + a_size + 2 * uv_size + 2 * uv0_size; // Security and validation checks if (width <= 0 || height <= 0 || // luma/alpha param error uv_width < 0 || uv_height < 0) { // u/v param error return 0; } // Clear previous buffer and allocate a new one. WebPPictureFree(picture); // erase previous buffer mem = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*mem)); if (mem == NULL) return 0; // From now on, we're in the clear, we can no longer fail... picture->memory_ = (void*)mem; picture->y_stride = y_stride; picture->uv_stride = uv_stride; picture->a_stride = a_stride; picture->uv0_stride = uv0_stride; // TODO(skal): we could align the y/u/v planes and adjust stride. picture->y = mem; mem += y_size; picture->u = mem; mem += uv_size; picture->v = mem; mem += uv_size; if (a_size) { picture->a = mem; mem += a_size; } if (uv0_size) { picture->u0 = mem; mem += uv0_size; picture->v0 = mem; mem += uv0_size; } (void)mem; // makes the static analyzer happy } else { void* memory; const uint64_t argb_size = (uint64_t)width * height; if (width <= 0 || height <= 0) { return 0; } // Clear previous buffer and allocate a new one. WebPPictureFree(picture); // erase previous buffer memory = WebPSafeMalloc(argb_size, sizeof(*picture->argb)); if (memory == NULL) return 0; // TODO(skal): align plane to cache line? picture->memory_argb_ = memory; picture->argb = (uint32_t*)memory; picture->argb_stride = width; } } return 1; } // Remove reference to the ARGB buffer (doesn't free anything). static void PictureResetARGB(WebPPicture* const picture) { picture->memory_argb_ = NULL; picture->argb = NULL; picture->argb_stride = 0; } // Remove reference to the YUVA buffer (doesn't free anything). static void PictureResetYUVA(WebPPicture* const picture) { picture->memory_ = NULL; picture->y = picture->u = picture->v = picture->a = NULL; picture->u0 = picture->v0 = NULL; picture->y_stride = picture->uv_stride = 0; picture->a_stride = 0; picture->uv0_stride = 0; } // Grab the 'specs' (writer, *opaque, width, height...) from 'src' and copy them // into 'dst'. Mark 'dst' as not owning any memory. static void WebPPictureGrabSpecs(const WebPPicture* const src, WebPPicture* const dst) { assert(src != NULL && dst != NULL); *dst = *src; PictureResetYUVA(dst); PictureResetARGB(dst); } // Allocate a new argb buffer, discarding any existing one and preserving // the other YUV(A) buffer. static int PictureAllocARGB(WebPPicture* const picture) { WebPPicture tmp; free(picture->memory_argb_); PictureResetARGB(picture); picture->use_argb = 1; WebPPictureGrabSpecs(picture, &tmp); if (!WebPPictureAlloc(&tmp)) { return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); } picture->memory_argb_ = tmp.memory_argb_; picture->argb = tmp.argb; picture->argb_stride = tmp.argb_stride; return 1; } // Release memory owned by 'picture' (both YUV and ARGB buffers). void WebPPictureFree(WebPPicture* picture) { if (picture != NULL) { free(picture->memory_); free(picture->memory_argb_); PictureResetYUVA(picture); PictureResetARGB(picture); } } //------------------------------------------------------------------------------ // Picture copying // Not worth moving to dsp/enc.c (only used here). static void CopyPlane(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width, int height) { while (height-- > 0) { memcpy(dst, src, width); src += src_stride; dst += dst_stride; } } // Adjust top-left corner to chroma sample position. static void SnapTopLeftPosition(const WebPPicture* const pic, int* const left, int* const top) { if (!pic->use_argb) { const int is_yuv422 = IS_YUV_CSP(pic->colorspace, WEBP_YUV422); if (IS_YUV_CSP(pic->colorspace, WEBP_YUV420) || is_yuv422) { *left &= ~1; if (!is_yuv422) *top &= ~1; } } } // Adjust top-left corner and verify that the sub-rectangle is valid. static int AdjustAndCheckRectangle(const WebPPicture* const pic, int* const left, int* const top, int width, int height) { SnapTopLeftPosition(pic, left, top); if ((*left) < 0 || (*top) < 0) return 0; if (width <= 0 || height <= 0) return 0; if ((*left) + width > pic->width) return 0; if ((*top) + height > pic->height) return 0; return 1; } int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) { if (src == NULL || dst == NULL) return 0; if (src == dst) return 1; WebPPictureGrabSpecs(src, dst); if (!WebPPictureAlloc(dst)) return 0; if (!src->use_argb) { CopyPlane(src->y, src->y_stride, dst->y, dst->y_stride, dst->width, dst->height); CopyPlane(src->u, src->uv_stride, dst->u, dst->uv_stride, HALVE(dst->width), HALVE(dst->height)); CopyPlane(src->v, src->uv_stride, dst->v, dst->uv_stride, HALVE(dst->width), HALVE(dst->height)); if (dst->a != NULL) { CopyPlane(src->a, src->a_stride, dst->a, dst->a_stride, dst->width, dst->height); } #ifdef WEBP_EXPERIMENTAL_FEATURES if (dst->u0 != NULL) { int uv0_width = src->width; if (IS_YUV_CSP(dst->colorspace, WEBP_YUV422)) { uv0_width = HALVE(uv0_width); } CopyPlane(src->u0, src->uv0_stride, dst->u0, dst->uv0_stride, uv0_width, dst->height); CopyPlane(src->v0, src->uv0_stride, dst->v0, dst->uv0_stride, uv0_width, dst->height); } #endif } else { CopyPlane((const uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb, 4 * dst->argb_stride, 4 * dst->width, dst->height); } return 1; } int WebPPictureIsView(const WebPPicture* picture) { if (picture == NULL) return 0; if (picture->use_argb) { return (picture->memory_argb_ == NULL); } return (picture->memory_ == NULL); } int WebPPictureView(const WebPPicture* src, int left, int top, int width, int height, WebPPicture* dst) { if (src == NULL || dst == NULL) return 0; // verify rectangle position. if (!AdjustAndCheckRectangle(src, &left, &top, width, height)) return 0; if (src != dst) { // beware of aliasing! We don't want to leak 'memory_'. WebPPictureGrabSpecs(src, dst); } dst->width = width; dst->height = height; if (!src->use_argb) { dst->y = src->y + top * src->y_stride + left; dst->u = src->u + (top >> 1) * src->uv_stride + (left >> 1); dst->v = src->v + (top >> 1) * src->uv_stride + (left >> 1); dst->y_stride = src->y_stride; dst->uv_stride = src->uv_stride; if (src->a != NULL) { dst->a = src->a + top * src->a_stride + left; dst->a_stride = src->a_stride; } #ifdef WEBP_EXPERIMENTAL_FEATURES if (src->u0 != NULL) { const int left_pos = IS_YUV_CSP(dst->colorspace, WEBP_YUV422) ? (left >> 1) : left; dst->u0 = src->u0 + top * src->uv0_stride + left_pos; dst->v0 = src->v0 + top * src->uv0_stride + left_pos; dst->uv0_stride = src->uv0_stride; } #endif } else { dst->argb = src->argb + top * src->argb_stride + left; dst->argb_stride = src->argb_stride; } return 1; } //------------------------------------------------------------------------------ // Picture cropping int WebPPictureCrop(WebPPicture* pic, int left, int top, int width, int height) { WebPPicture tmp; if (pic == NULL) return 0; if (!AdjustAndCheckRectangle(pic, &left, &top, width, height)) return 0; WebPPictureGrabSpecs(pic, &tmp); tmp.width = width; tmp.height = height; if (!WebPPictureAlloc(&tmp)) return 0; if (!pic->use_argb) { const int y_offset = top * pic->y_stride + left; const int uv_offset = (top / 2) * pic->uv_stride + left / 2; CopyPlane(pic->y + y_offset, pic->y_stride, tmp.y, tmp.y_stride, width, height); CopyPlane(pic->u + uv_offset, pic->uv_stride, tmp.u, tmp.uv_stride, HALVE(width), HALVE(height)); CopyPlane(pic->v + uv_offset, pic->uv_stride, tmp.v, tmp.uv_stride, HALVE(width), HALVE(height)); if (tmp.a != NULL) { const int a_offset = top * pic->a_stride + left; CopyPlane(pic->a + a_offset, pic->a_stride, tmp.a, tmp.a_stride, width, height); } #ifdef WEBP_EXPERIMENTAL_FEATURES if (tmp.u0 != NULL) { int w = width; int left_pos = left; if (IS_YUV_CSP(tmp.colorspace, WEBP_YUV422)) { w = HALVE(w); left_pos = HALVE(left_pos); } CopyPlane(pic->u0 + top * pic->uv0_stride + left_pos, pic->uv0_stride, tmp.u0, tmp.uv0_stride, w, height); CopyPlane(pic->v0 + top * pic->uv0_stride + left_pos, pic->uv0_stride, tmp.v0, tmp.uv0_stride, w, height); } #endif } else { const uint8_t* const src = (const uint8_t*)(pic->argb + top * pic->argb_stride + left); CopyPlane(src, pic->argb_stride * 4, (uint8_t*)tmp.argb, tmp.argb_stride * 4, width * 4, height); } WebPPictureFree(pic); *pic = tmp; return 1; } //------------------------------------------------------------------------------ // Simple picture rescaler static void RescalePlane(const uint8_t* src, int src_width, int src_height, int src_stride, uint8_t* dst, int dst_width, int dst_height, int dst_stride, int32_t* const work, int num_channels) { WebPRescaler rescaler; int y = 0; WebPRescalerInit(&rescaler, src_width, src_height, dst, dst_width, dst_height, dst_stride, num_channels, src_width, dst_width, src_height, dst_height, work); memset(work, 0, 2 * dst_width * num_channels * sizeof(*work)); while (y < src_height) { y += WebPRescalerImport(&rescaler, src_height - y, src + y * src_stride, src_stride); WebPRescalerExport(&rescaler); } } static void AlphaMultiplyARGB(WebPPicture* const pic, int inverse) { uint32_t* ptr = pic->argb; int y; for (y = 0; y < pic->height; ++y) { WebPMultARGBRow(ptr, pic->width, inverse); ptr += pic->argb_stride; } } static void AlphaMultiplyY(WebPPicture* const pic, int inverse) { const uint8_t* ptr_a = pic->a; if (ptr_a != NULL) { uint8_t* ptr_y = pic->y; int y; for (y = 0; y < pic->height; ++y) { WebPMultRow(ptr_y, ptr_a, pic->width, inverse); ptr_y += pic->y_stride; ptr_a += pic->a_stride; } } } int WebPPictureRescale(WebPPicture* pic, int width, int height) { WebPPicture tmp; int prev_width, prev_height; int32_t* work; if (pic == NULL) return 0; prev_width = pic->width; prev_height = pic->height; // if width is unspecified, scale original proportionally to height ratio. if (width == 0) { width = (prev_width * height + prev_height / 2) / prev_height; } // if height is unspecified, scale original proportionally to width ratio. if (height == 0) { height = (prev_height * width + prev_width / 2) / prev_width; } // Check if the overall dimensions still make sense. if (width <= 0 || height <= 0) return 0; WebPPictureGrabSpecs(pic, &tmp); tmp.width = width; tmp.height = height; if (!WebPPictureAlloc(&tmp)) return 0; if (!pic->use_argb) { work = (int32_t*)WebPSafeMalloc(2ULL * width, sizeof(*work)); if (work == NULL) { WebPPictureFree(&tmp); return 0; } // If present, we need to rescale alpha first (for AlphaMultiplyY). if (pic->a != NULL) { RescalePlane(pic->a, prev_width, prev_height, pic->a_stride, tmp.a, width, height, tmp.a_stride, work, 1); } // We take transparency into account on the luma plane only. That's not // totally exact blending, but still is a good approximation. AlphaMultiplyY(pic, 0); RescalePlane(pic->y, prev_width, prev_height, pic->y_stride, tmp.y, width, height, tmp.y_stride, work, 1); AlphaMultiplyY(&tmp, 1); RescalePlane(pic->u, HALVE(prev_width), HALVE(prev_height), pic->uv_stride, tmp.u, HALVE(width), HALVE(height), tmp.uv_stride, work, 1); RescalePlane(pic->v, HALVE(prev_width), HALVE(prev_height), pic->uv_stride, tmp.v, HALVE(width), HALVE(height), tmp.uv_stride, work, 1); #ifdef WEBP_EXPERIMENTAL_FEATURES if (tmp.u0 != NULL) { const int s = IS_YUV_CSP(tmp.colorspace, WEBP_YUV422) ? 2 : 1; RescalePlane( pic->u0, (prev_width + s / 2) / s, prev_height, pic->uv0_stride, tmp.u0, (width + s / 2) / s, height, tmp.uv0_stride, work, 1); RescalePlane( pic->v0, (prev_width + s / 2) / s, prev_height, pic->uv0_stride, tmp.v0, (width + s / 2) / s, height, tmp.uv0_stride, work, 1); } #endif } else { work = (int32_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work)); if (work == NULL) { WebPPictureFree(&tmp); return 0; } // In order to correctly interpolate colors, we need to apply the alpha // weighting first (black-matting), scale the RGB values, and remove // the premultiplication afterward (while preserving the alpha channel). AlphaMultiplyARGB(pic, 0); RescalePlane((const uint8_t*)pic->argb, prev_width, prev_height, pic->argb_stride * 4, (uint8_t*)tmp.argb, width, height, tmp.argb_stride * 4, work, 4); AlphaMultiplyARGB(&tmp, 1); } WebPPictureFree(pic); free(work); *pic = tmp; return 1; } //------------------------------------------------------------------------------ // WebPMemoryWriter: Write-to-memory void WebPMemoryWriterInit(WebPMemoryWriter* writer) { writer->mem = NULL; writer->size = 0; writer->max_size = 0; } int WebPMemoryWrite(const uint8_t* data, size_t data_size, const WebPPicture* picture) { WebPMemoryWriter* const w = (WebPMemoryWriter*)picture->custom_ptr; uint64_t next_size; if (w == NULL) { return 1; } next_size = (uint64_t)w->size + data_size; if (next_size > w->max_size) { uint8_t* new_mem; uint64_t next_max_size = 2ULL * w->max_size; if (next_max_size < next_size) next_max_size = next_size; if (next_max_size < 8192ULL) next_max_size = 8192ULL; new_mem = (uint8_t*)WebPSafeMalloc(next_max_size, 1); if (new_mem == NULL) { return 0; } if (w->size > 0) { memcpy(new_mem, w->mem, w->size); } free(w->mem); w->mem = new_mem; // down-cast is ok, thanks to WebPSafeMalloc w->max_size = (size_t)next_max_size; } if (data_size > 0) { memcpy(w->mem + w->size, data, data_size); w->size += data_size; } return 1; } //------------------------------------------------------------------------------ // Detection of non-trivial transparency // Returns true if alpha[] has non-0xff values. static int CheckNonOpaque(const uint8_t* alpha, int width, int height, int x_step, int y_step) { if (alpha == NULL) return 0; while (height-- > 0) { int x; for (x = 0; x < width * x_step; x += x_step) { if (alpha[x] != 0xff) return 1; // TODO(skal): check 4/8 bytes at a time. } alpha += y_step; } return 0; } // Checking for the presence of non-opaque alpha. int WebPPictureHasTransparency(const WebPPicture* picture) { if (picture == NULL) return 0; if (!picture->use_argb) { return CheckNonOpaque(picture->a, picture->width, picture->height, 1, picture->a_stride); } else { int x, y; const uint32_t* argb = picture->argb; if (argb == NULL) return 0; for (y = 0; y < picture->height; ++y) { for (x = 0; x < picture->width; ++x) { if (argb[x] < 0xff000000u) return 1; // test any alpha values != 0xff } argb += picture->argb_stride; } } return 0; } //------------------------------------------------------------------------------ // RGB -> YUV conversion static int RGBToY(int r, int g, int b, VP8Random* const rg) { return VP8RGBToY(r, g, b, VP8RandomBits(rg, YUV_FIX)); } static int RGBToU(int r, int g, int b, VP8Random* const rg) { return VP8RGBToU(r, g, b, VP8RandomBits(rg, YUV_FIX + 2)); } static int RGBToV(int r, int g, int b, VP8Random* const rg) { return VP8RGBToV(r, g, b, VP8RandomBits(rg, YUV_FIX + 2)); } //------------------------------------------------------------------------------ #if defined(USE_GAMMA_COMPRESSION) // gamma-compensates loss of resolution during chroma subsampling #define kGamma 0.80 #define kGammaFix 12 // fixed-point precision for linear values #define kGammaScale ((1 << kGammaFix) - 1) #define kGammaTabFix 7 // fixed-point fractional bits precision #define kGammaTabScale (1 << kGammaTabFix) #define kGammaTabRounder (kGammaTabScale >> 1) #define kGammaTabSize (1 << (kGammaFix - kGammaTabFix)) static int kLinearToGammaTab[kGammaTabSize + 1]; static uint16_t kGammaToLinearTab[256]; static int kGammaTablesOk = 0; static void InitGammaTables(void) { if (!kGammaTablesOk) { int v; const double scale = 1. / kGammaScale; for (v = 0; v <= 255; ++v) { kGammaToLinearTab[v] = (uint16_t)(pow(v / 255., kGamma) * kGammaScale + .5); } for (v = 0; v <= kGammaTabSize; ++v) { const double x = scale * (v << kGammaTabFix); kLinearToGammaTab[v] = (int)(pow(x, 1. / kGamma) * 255. + .5); } kGammaTablesOk = 1; } } static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return kGammaToLinearTab[v]; } // Convert a linear value 'v' to YUV_FIX+2 fixed-point precision // U/V value, suitable for RGBToU/V calls. static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) { const int v = base_value << shift; // final uplifted value const int tab_pos = v >> (kGammaTabFix + 2); // integer part const int x = v & ((kGammaTabScale << 2) - 1); // fractional part const int v0 = kLinearToGammaTab[tab_pos]; const int v1 = kLinearToGammaTab[tab_pos + 1]; const int y = v1 * x + v0 * ((kGammaTabScale << 2) - x); // interpolate return (y + kGammaTabRounder) >> kGammaTabFix; // descale } #else static void InitGammaTables(void) {} static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return v; } static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) { (void)shift; return v; } #endif // USE_GAMMA_COMPRESSION //------------------------------------------------------------------------------ #define SUM4(ptr) LinearToGamma( \ GammaToLinear((ptr)[0]) + \ GammaToLinear((ptr)[step]) + \ GammaToLinear((ptr)[rgb_stride]) + \ GammaToLinear((ptr)[rgb_stride + step]), 0) \ #define SUM2H(ptr) \ LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[step]), 1) #define SUM2V(ptr) \ LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[rgb_stride]), 1) #define SUM1(ptr) \ LinearToGamma(GammaToLinear((ptr)[0]), 2) #define RGB_TO_UV(x, y, SUM) { \ const int src = (2 * (step * (x) + (y) * rgb_stride)); \ const int dst = (x) + (y) * picture->uv_stride; \ const int r = SUM(r_ptr + src); \ const int g = SUM(g_ptr + src); \ const int b = SUM(b_ptr + src); \ picture->u[dst] = RGBToU(r, g, b, &rg); \ picture->v[dst] = RGBToV(r, g, b, &rg); \ } #define RGB_TO_UV0(x_in, x_out, y, SUM) { \ const int src = (step * (x_in) + (y) * rgb_stride); \ const int dst = (x_out) + (y) * picture->uv0_stride; \ const int r = SUM(r_ptr + src); \ const int g = SUM(g_ptr + src); \ const int b = SUM(b_ptr + src); \ picture->u0[dst] = RGBToU(r, g, b, &rg); \ picture->v0[dst] = RGBToV(r, g, b, &rg); \ } static void MakeGray(WebPPicture* const picture) { int y; const int uv_width = HALVE(picture->width); const int uv_height = HALVE(picture->height); for (y = 0; y < uv_height; ++y) { memset(picture->u + y * picture->uv_stride, 128, uv_width); memset(picture->v + y * picture->uv_stride, 128, uv_width); } } static int ImportYUVAFromRGBA(const uint8_t* const r_ptr, const uint8_t* const g_ptr, const uint8_t* const b_ptr, const uint8_t* const a_ptr, int step, // bytes per pixel int rgb_stride, // bytes per scanline float dithering, WebPPicture* const picture) { const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK; int x, y; const int width = picture->width; const int height = picture->height; const int has_alpha = CheckNonOpaque(a_ptr, width, height, step, rgb_stride); VP8Random rg; picture->colorspace = uv_csp; picture->use_argb = 0; if (has_alpha) { picture->colorspace |= WEBP_CSP_ALPHA_BIT; } if (!WebPPictureAlloc(picture)) return 0; VP8InitRandom(&rg, dithering); InitGammaTables(); // Import luma plane for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { const int offset = step * x + y * rgb_stride; picture->y[x + y * picture->y_stride] = RGBToY(r_ptr[offset], g_ptr[offset], b_ptr[offset], &rg); } } // Downsample U/V plane if (uv_csp != WEBP_YUV400) { for (y = 0; y < (height >> 1); ++y) { for (x = 0; x < (width >> 1); ++x) { RGB_TO_UV(x, y, SUM4); } if (width & 1) { RGB_TO_UV(x, y, SUM2V); } } if (height & 1) { for (x = 0; x < (width >> 1); ++x) { RGB_TO_UV(x, y, SUM2H); } if (width & 1) { RGB_TO_UV(x, y, SUM1); } } #ifdef WEBP_EXPERIMENTAL_FEATURES // Store original U/V samples too if (uv_csp == WEBP_YUV422) { for (y = 0; y < height; ++y) { for (x = 0; x < (width >> 1); ++x) { RGB_TO_UV0(2 * x, x, y, SUM2H); } if (width & 1) { RGB_TO_UV0(2 * x, x, y, SUM1); } } } else if (uv_csp == WEBP_YUV444) { for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { RGB_TO_UV0(x, x, y, SUM1); } } } #endif } else { MakeGray(picture); } if (has_alpha) { assert(step >= 4); assert(picture->a != NULL); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { picture->a[x + y * picture->a_stride] = a_ptr[step * x + y * rgb_stride]; } } } return 1; } static int Import(WebPPicture* const picture, const uint8_t* const rgb, int rgb_stride, int step, int swap_rb, int import_alpha) { const uint8_t* const r_ptr = rgb + (swap_rb ? 2 : 0); const uint8_t* const g_ptr = rgb + 1; const uint8_t* const b_ptr = rgb + (swap_rb ? 0 : 2); const uint8_t* const a_ptr = import_alpha ? rgb + 3 : NULL; const int width = picture->width; const int height = picture->height; if (!picture->use_argb) { return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride, 0.f /* no dithering */, picture); } if (import_alpha) { picture->colorspace |= WEBP_CSP_ALPHA_BIT; } else { picture->colorspace &= ~WEBP_CSP_ALPHA_BIT; } if (!WebPPictureAlloc(picture)) return 0; if (!import_alpha) { int x, y; for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { const int offset = step * x + y * rgb_stride; const uint32_t argb = MakeARGB32(r_ptr[offset], g_ptr[offset], b_ptr[offset]); picture->argb[x + y * picture->argb_stride] = argb; } } } else { int x, y; assert(step >= 4); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { const int offset = step * x + y * rgb_stride; const uint32_t argb = ((uint32_t)a_ptr[offset] << 24) | (r_ptr[offset] << 16) | (g_ptr[offset] << 8) | (b_ptr[offset]); picture->argb[x + y * picture->argb_stride] = argb; } } } return 1; } #undef SUM4 #undef SUM2V #undef SUM2H #undef SUM1 #undef RGB_TO_UV int WebPPictureImportRGB(WebPPicture* picture, const uint8_t* rgb, int rgb_stride) { return Import(picture, rgb, rgb_stride, 3, 0, 0); } int WebPPictureImportBGR(WebPPicture* picture, const uint8_t* rgb, int rgb_stride) { return Import(picture, rgb, rgb_stride, 3, 1, 0); } int WebPPictureImportRGBA(WebPPicture* picture, const uint8_t* rgba, int rgba_stride) { return Import(picture, rgba, rgba_stride, 4, 0, 1); } int WebPPictureImportBGRA(WebPPicture* picture, const uint8_t* rgba, int rgba_stride) { return Import(picture, rgba, rgba_stride, 4, 1, 1); } int WebPPictureImportRGBX(WebPPicture* picture, const uint8_t* rgba, int rgba_stride) { return Import(picture, rgba, rgba_stride, 4, 0, 0); } int WebPPictureImportBGRX(WebPPicture* picture, const uint8_t* rgba, int rgba_stride) { return Import(picture, rgba, rgba_stride, 4, 1, 0); } //------------------------------------------------------------------------------ // Automatic YUV <-> ARGB conversions. int WebPPictureYUVAToARGB(WebPPicture* picture) { if (picture == NULL) return 0; if (picture->y == NULL || picture->u == NULL || picture->v == NULL) { return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER); } if ((picture->colorspace & WEBP_CSP_ALPHA_BIT) && picture->a == NULL) { return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER); } if ((picture->colorspace & WEBP_CSP_UV_MASK) != WEBP_YUV420) { return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION); } // Allocate a new argb buffer (discarding the previous one). if (!PictureAllocARGB(picture)) return 0; // Convert { int y; const int width = picture->width; const int height = picture->height; const int argb_stride = 4 * picture->argb_stride; uint8_t* dst = (uint8_t*)picture->argb; const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y; WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST); // First row, with replicated top samples. upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width); cur_y += picture->y_stride; dst += argb_stride; // Center rows. for (y = 1; y + 1 < height; y += 2) { const uint8_t* const top_u = cur_u; const uint8_t* const top_v = cur_v; cur_u += picture->uv_stride; cur_v += picture->uv_stride; upsample(cur_y, cur_y + picture->y_stride, top_u, top_v, cur_u, cur_v, dst, dst + argb_stride, width); cur_y += 2 * picture->y_stride; dst += 2 * argb_stride; } // Last row (if needed), with replicated bottom samples. if (height > 1 && !(height & 1)) { upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width); } // Insert alpha values if needed, in replacement for the default 0xff ones. if (picture->colorspace & WEBP_CSP_ALPHA_BIT) { for (y = 0; y < height; ++y) { uint32_t* const argb_dst = picture->argb + y * picture->argb_stride; const uint8_t* const src = picture->a + y * picture->a_stride; int x; for (x = 0; x < width; ++x) { argb_dst[x] = (argb_dst[x] & 0x00ffffffu) | ((uint32_t)src[x] << 24); } } } } return 1; } int WebPPictureARGBToYUVADithered(WebPPicture* picture, WebPEncCSP colorspace, float dithering) { if (picture == NULL) return 0; if (picture->argb == NULL) { return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER); } else { const uint8_t* const argb = (const uint8_t*)picture->argb; const uint8_t* const r = ALPHA_IS_LAST ? argb + 2 : argb + 1; const uint8_t* const g = ALPHA_IS_LAST ? argb + 1 : argb + 2; const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3; const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0; // We work on a tmp copy of 'picture', because ImportYUVAFromRGBA() // would be calling WebPPictureFree(picture) otherwise. WebPPicture tmp = *picture; PictureResetARGB(&tmp); // reset ARGB buffer so that it's not free()'d. tmp.use_argb = 0; tmp.colorspace = colorspace & WEBP_CSP_UV_MASK; if (!ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, dithering, &tmp)) { return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); } // Copy back the YUV specs into 'picture'. tmp.argb = picture->argb; tmp.argb_stride = picture->argb_stride; tmp.memory_argb_ = picture->memory_argb_; *picture = tmp; } return 1; } int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace) { return WebPPictureARGBToYUVADithered(picture, colorspace, 0.f); } //------------------------------------------------------------------------------ // Helper: clean up fully transparent area to help compressibility. #define SIZE 8 #define SIZE2 (SIZE / 2) static int is_transparent_area(const uint8_t* ptr, int stride, int size) { int y, x; for (y = 0; y < size; ++y) { for (x = 0; x < size; ++x) { if (ptr[x]) { return 0; } } ptr += stride; } return 1; } static WEBP_INLINE void flatten(uint8_t* ptr, int v, int stride, int size) { int y; for (y = 0; y < size; ++y) { memset(ptr, v, size); ptr += stride; } } void WebPCleanupTransparentArea(WebPPicture* pic) { int x, y, w, h; const uint8_t* a_ptr; int values[3] = { 0 }; if (pic == NULL) return; a_ptr = pic->a; if (a_ptr == NULL) return; // nothing to do w = pic->width / SIZE; h = pic->height / SIZE; for (y = 0; y < h; ++y) { int need_reset = 1; for (x = 0; x < w; ++x) { const int off_a = (y * pic->a_stride + x) * SIZE; const int off_y = (y * pic->y_stride + x) * SIZE; const int off_uv = (y * pic->uv_stride + x) * SIZE2; if (is_transparent_area(a_ptr + off_a, pic->a_stride, SIZE)) { if (need_reset) { values[0] = pic->y[off_y]; values[1] = pic->u[off_uv]; values[2] = pic->v[off_uv]; need_reset = 0; } flatten(pic->y + off_y, values[0], pic->y_stride, SIZE); flatten(pic->u + off_uv, values[1], pic->uv_stride, SIZE2); flatten(pic->v + off_uv, values[2], pic->uv_stride, SIZE2); } else { need_reset = 1; } } // ignore the left-overs on right/bottom } } #undef SIZE #undef SIZE2 //------------------------------------------------------------------------------ // Blend color and remove transparency info #define BLEND(V0, V1, ALPHA) \ ((((V0) * (255 - (ALPHA)) + (V1) * (ALPHA)) * 0x101) >> 16) #define BLEND_10BIT(V0, V1, ALPHA) \ ((((V0) * (1020 - (ALPHA)) + (V1) * (ALPHA)) * 0x101) >> 18) void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb) { const int red = (background_rgb >> 16) & 0xff; const int green = (background_rgb >> 8) & 0xff; const int blue = (background_rgb >> 0) & 0xff; VP8Random rg; int x, y; if (pic == NULL) return; VP8InitRandom(&rg, 0.f); if (!pic->use_argb) { const int uv_width = (pic->width >> 1); // omit last pixel during u/v loop const int Y0 = RGBToY(red, green, blue, &rg); // VP8RGBToU/V expects the u/v values summed over four pixels const int U0 = RGBToU(4 * red, 4 * green, 4 * blue, &rg); const int V0 = RGBToV(4 * red, 4 * green, 4 * blue, &rg); const int has_alpha = pic->colorspace & WEBP_CSP_ALPHA_BIT; if (!has_alpha || pic->a == NULL) return; // nothing to do for (y = 0; y < pic->height; ++y) { // Luma blending uint8_t* const y_ptr = pic->y + y * pic->y_stride; uint8_t* const a_ptr = pic->a + y * pic->a_stride; for (x = 0; x < pic->width; ++x) { const int alpha = a_ptr[x]; if (alpha < 0xff) { y_ptr[x] = BLEND(Y0, y_ptr[x], a_ptr[x]); } } // Chroma blending every even line if ((y & 1) == 0) { uint8_t* const u = pic->u + (y >> 1) * pic->uv_stride; uint8_t* const v = pic->v + (y >> 1) * pic->uv_stride; uint8_t* const a_ptr2 = (y + 1 == pic->height) ? a_ptr : a_ptr + pic->a_stride; for (x = 0; x < uv_width; ++x) { // Average four alpha values into a single blending weight. // TODO(skal): might lead to visible contouring. Can we do better? const int alpha = a_ptr[2 * x + 0] + a_ptr[2 * x + 1] + a_ptr2[2 * x + 0] + a_ptr2[2 * x + 1]; u[x] = BLEND_10BIT(U0, u[x], alpha); v[x] = BLEND_10BIT(V0, v[x], alpha); } if (pic->width & 1) { // rightmost pixel const int alpha = 2 * (a_ptr[2 * x + 0] + a_ptr2[2 * x + 0]); u[x] = BLEND_10BIT(U0, u[x], alpha); v[x] = BLEND_10BIT(V0, v[x], alpha); } } memset(a_ptr, 0xff, pic->width); } } else { uint32_t* argb = pic->argb; const uint32_t background = MakeARGB32(red, green, blue); for (y = 0; y < pic->height; ++y) { for (x = 0; x < pic->width; ++x) { const int alpha = (argb[x] >> 24) & 0xff; if (alpha != 0xff) { if (alpha > 0) { int r = (argb[x] >> 16) & 0xff; int g = (argb[x] >> 8) & 0xff; int b = (argb[x] >> 0) & 0xff; r = BLEND(red, r, alpha); g = BLEND(green, g, alpha); b = BLEND(blue, b, alpha); argb[x] = MakeARGB32(r, g, b); } else { argb[x] = background; } } } argb += pic->argb_stride; } } } #undef BLEND #undef BLEND_10BIT //------------------------------------------------------------------------------ // local-min distortion // // For every pixel in the *reference* picture, we search for the local best // match in the compressed image. This is not a symmetrical measure. // search radius. Shouldn't be too large. #define RADIUS 2 static float AccumulateLSIM(const uint8_t* src, int src_stride, const uint8_t* ref, int ref_stride, int w, int h) { int x, y; double total_sse = 0.; for (y = 0; y < h; ++y) { const int y_0 = (y - RADIUS < 0) ? 0 : y - RADIUS; const int y_1 = (y + RADIUS + 1 >= h) ? h : y + RADIUS + 1; for (x = 0; x < w; ++x) { const int x_0 = (x - RADIUS < 0) ? 0 : x - RADIUS; const int x_1 = (x + RADIUS + 1 >= w) ? w : x + RADIUS + 1; double best_sse = 255. * 255.; const double value = (double)ref[y * ref_stride + x]; int i, j; for (j = y_0; j < y_1; ++j) { const uint8_t* s = src + j * src_stride; for (i = x_0; i < x_1; ++i) { const double sse = (double)(s[i] - value) * (s[i] - value); if (sse < best_sse) best_sse = sse; } } total_sse += best_sse; } } return (float)total_sse; } #undef RADIUS //------------------------------------------------------------------------------ // Distortion // Max value returned in case of exact similarity. static const double kMinDistortion_dB = 99.; static float GetPSNR(const double v) { return (float)((v > 0.) ? -4.3429448 * log(v / (255 * 255.)) : kMinDistortion_dB); } int WebPPictureDistortion(const WebPPicture* src, const WebPPicture* ref, int type, float result[5]) { DistoStats stats[5]; int has_alpha; int uv_w, uv_h; if (src == NULL || ref == NULL || src->width != ref->width || src->height != ref->height || src->y == NULL || ref->y == NULL || src->u == NULL || ref->u == NULL || src->v == NULL || ref->v == NULL || result == NULL) { return 0; } // TODO(skal): provide distortion for ARGB too. if (src->use_argb == 1 || src->use_argb != ref->use_argb) { return 0; } has_alpha = !!(src->colorspace & WEBP_CSP_ALPHA_BIT); if (has_alpha != !!(ref->colorspace & WEBP_CSP_ALPHA_BIT) || (has_alpha && (src->a == NULL || ref->a == NULL))) { return 0; } memset(stats, 0, sizeof(stats)); uv_w = HALVE(src->width); uv_h = HALVE(src->height); if (type >= 2) { float sse[4]; sse[0] = AccumulateLSIM(src->y, src->y_stride, ref->y, ref->y_stride, src->width, src->height); sse[1] = AccumulateLSIM(src->u, src->uv_stride, ref->u, ref->uv_stride, uv_w, uv_h); sse[2] = AccumulateLSIM(src->v, src->uv_stride, ref->v, ref->uv_stride, uv_w, uv_h); sse[3] = has_alpha ? AccumulateLSIM(src->a, src->a_stride, ref->a, ref->a_stride, src->width, src->height) : 0.f; result[0] = GetPSNR(sse[0] / (src->width * src->height)); result[1] = GetPSNR(sse[1] / (uv_w * uv_h)); result[2] = GetPSNR(sse[2] / (uv_w * uv_h)); result[3] = GetPSNR(sse[3] / (src->width * src->height)); { double total_sse = sse[0] + sse[1] + sse[2]; int total_pixels = src->width * src->height + 2 * uv_w * uv_h; if (has_alpha) { total_pixels += src->width * src->height; total_sse += sse[3]; } result[4] = GetPSNR(total_sse / total_pixels); } } else { int c; VP8SSIMAccumulatePlane(src->y, src->y_stride, ref->y, ref->y_stride, src->width, src->height, &stats[0]); VP8SSIMAccumulatePlane(src->u, src->uv_stride, ref->u, ref->uv_stride, uv_w, uv_h, &stats[1]); VP8SSIMAccumulatePlane(src->v, src->uv_stride, ref->v, ref->uv_stride, uv_w, uv_h, &stats[2]); if (has_alpha) { VP8SSIMAccumulatePlane(src->a, src->a_stride, ref->a, ref->a_stride, src->width, src->height, &stats[3]); } for (c = 0; c <= 4; ++c) { if (type == 1) { const double v = VP8SSIMGet(&stats[c]); result[c] = (float)((v < 1.) ? -10.0 * log10(1. - v) : kMinDistortion_dB); } else { const double v = VP8SSIMGetSquaredError(&stats[c]); result[c] = GetPSNR(v); } // Accumulate forward if (c < 4) VP8SSIMAddStats(&stats[c], &stats[4]); } } return 1; } //------------------------------------------------------------------------------ // Simplest high-level calls: typedef int (*Importer)(WebPPicture* const, const uint8_t* const, int); static size_t Encode(const uint8_t* rgba, int width, int height, int stride, Importer import, float quality_factor, int lossless, uint8_t** output) { WebPPicture pic; WebPConfig config; WebPMemoryWriter wrt; int ok; if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality_factor) || !WebPPictureInit(&pic)) { return 0; // shouldn't happen, except if system installation is broken } config.lossless = !!lossless; pic.use_argb = !!lossless; pic.width = width; pic.height = height; pic.writer = WebPMemoryWrite; pic.custom_ptr = &wrt; WebPMemoryWriterInit(&wrt); ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic); WebPPictureFree(&pic); if (!ok) { free(wrt.mem); *output = NULL; return 0; } *output = wrt.mem; return wrt.size; } #define ENCODE_FUNC(NAME, IMPORTER) \ size_t NAME(const uint8_t* in, int w, int h, int bps, float q, \ uint8_t** out) { \ return Encode(in, w, h, bps, IMPORTER, q, 0, out); \ } ENCODE_FUNC(WebPEncodeRGB, WebPPictureImportRGB) ENCODE_FUNC(WebPEncodeBGR, WebPPictureImportBGR) ENCODE_FUNC(WebPEncodeRGBA, WebPPictureImportRGBA) ENCODE_FUNC(WebPEncodeBGRA, WebPPictureImportBGRA) #undef ENCODE_FUNC #define LOSSLESS_DEFAULT_QUALITY 70. #define LOSSLESS_ENCODE_FUNC(NAME, IMPORTER) \ size_t NAME(const uint8_t* in, int w, int h, int bps, uint8_t** out) { \ return Encode(in, w, h, bps, IMPORTER, LOSSLESS_DEFAULT_QUALITY, 1, out); \ } LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGB, WebPPictureImportRGB) LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGR, WebPPictureImportBGR) LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGBA, WebPPictureImportRGBA) LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGRA, WebPPictureImportBGRA) #undef LOSSLESS_ENCODE_FUNC //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/analysis.c0000644000014400001440000004067412255002107013377 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Macroblock analysis // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #include "./vp8enci.h" #include "./cost.h" #include "../utils/utils.h" #define MAX_ITERS_K_MEANS 6 //------------------------------------------------------------------------------ // Smooth the segment map by replacing isolated block by the majority of its // neighbours. static void SmoothSegmentMap(VP8Encoder* const enc) { int n, x, y; const int w = enc->mb_w_; const int h = enc->mb_h_; const int majority_cnt_3_x_3_grid = 5; uint8_t* const tmp = (uint8_t*)WebPSafeMalloc((uint64_t)w * h, sizeof(*tmp)); assert((uint64_t)(w * h) == (uint64_t)w * h); // no overflow, as per spec if (tmp == NULL) return; for (y = 1; y < h - 1; ++y) { for (x = 1; x < w - 1; ++x) { int cnt[NUM_MB_SEGMENTS] = { 0 }; const VP8MBInfo* const mb = &enc->mb_info_[x + w * y]; int majority_seg = mb->segment_; // Check the 8 neighbouring segment values. cnt[mb[-w - 1].segment_]++; // top-left cnt[mb[-w + 0].segment_]++; // top cnt[mb[-w + 1].segment_]++; // top-right cnt[mb[ - 1].segment_]++; // left cnt[mb[ + 1].segment_]++; // right cnt[mb[ w - 1].segment_]++; // bottom-left cnt[mb[ w + 0].segment_]++; // bottom cnt[mb[ w + 1].segment_]++; // bottom-right for (n = 0; n < NUM_MB_SEGMENTS; ++n) { if (cnt[n] >= majority_cnt_3_x_3_grid) { majority_seg = n; break; } } tmp[x + y * w] = majority_seg; } } for (y = 1; y < h - 1; ++y) { for (x = 1; x < w - 1; ++x) { VP8MBInfo* const mb = &enc->mb_info_[x + w * y]; mb->segment_ = tmp[x + y * w]; } } free(tmp); } //------------------------------------------------------------------------------ // set segment susceptibility alpha_ / beta_ static WEBP_INLINE int clip(int v, int m, int M) { return (v < m) ? m : (v > M) ? M : v; } static void SetSegmentAlphas(VP8Encoder* const enc, const int centers[NUM_MB_SEGMENTS], int mid) { const int nb = enc->segment_hdr_.num_segments_; int min = centers[0], max = centers[0]; int n; if (nb > 1) { for (n = 0; n < nb; ++n) { if (min > centers[n]) min = centers[n]; if (max < centers[n]) max = centers[n]; } } if (max == min) max = min + 1; assert(mid <= max && mid >= min); for (n = 0; n < nb; ++n) { const int alpha = 255 * (centers[n] - mid) / (max - min); const int beta = 255 * (centers[n] - min) / (max - min); enc->dqm_[n].alpha_ = clip(alpha, -127, 127); enc->dqm_[n].beta_ = clip(beta, 0, 255); } } //------------------------------------------------------------------------------ // Compute susceptibility based on DCT-coeff histograms: // the higher, the "easier" the macroblock is to compress. #define MAX_ALPHA 255 // 8b of precision for susceptibilities. #define ALPHA_SCALE (2 * MAX_ALPHA) // scaling factor for alpha. #define DEFAULT_ALPHA (-1) #define IS_BETTER_ALPHA(alpha, best_alpha) ((alpha) > (best_alpha)) static int FinalAlphaValue(int alpha) { alpha = MAX_ALPHA - alpha; return clip(alpha, 0, MAX_ALPHA); } static int GetAlpha(const VP8Histogram* const histo) { int max_value = 0, last_non_zero = 1; int k; int alpha; for (k = 0; k <= MAX_COEFF_THRESH; ++k) { const int value = histo->distribution[k]; if (value > 0) { if (value > max_value) max_value = value; last_non_zero = k; } } // 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer // values which happen to be mostly noise. This leaves the maximum precision // for handling the useful small values which contribute most. alpha = (max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0; return alpha; } static void MergeHistograms(const VP8Histogram* const in, VP8Histogram* const out) { int i; for (i = 0; i <= MAX_COEFF_THRESH; ++i) { out->distribution[i] += in->distribution[i]; } } //------------------------------------------------------------------------------ // Simplified k-Means, to assign Nb segments based on alpha-histogram static void AssignSegments(VP8Encoder* const enc, const int alphas[MAX_ALPHA + 1]) { const int nb = enc->segment_hdr_.num_segments_; int centers[NUM_MB_SEGMENTS]; int weighted_average = 0; int map[MAX_ALPHA + 1]; int a, n, k; int min_a = 0, max_a = MAX_ALPHA, range_a; // 'int' type is ok for histo, and won't overflow int accum[NUM_MB_SEGMENTS], dist_accum[NUM_MB_SEGMENTS]; assert(nb >= 1); // bracket the input for (n = 0; n <= MAX_ALPHA && alphas[n] == 0; ++n) {} min_a = n; for (n = MAX_ALPHA; n > min_a && alphas[n] == 0; --n) {} max_a = n; range_a = max_a - min_a; // Spread initial centers evenly for (k = 0, n = 1; k < nb; ++k, n += 2) { assert(n < 2 * nb); centers[k] = min_a + (n * range_a) / (2 * nb); } for (k = 0; k < MAX_ITERS_K_MEANS; ++k) { // few iters are enough int total_weight; int displaced; // Reset stats for (n = 0; n < nb; ++n) { accum[n] = 0; dist_accum[n] = 0; } // Assign nearest center for each 'a' n = 0; // track the nearest center for current 'a' for (a = min_a; a <= max_a; ++a) { if (alphas[a]) { while (n + 1 < nb && abs(a - centers[n + 1]) < abs(a - centers[n])) { n++; } map[a] = n; // accumulate contribution into best centroid dist_accum[n] += a * alphas[a]; accum[n] += alphas[a]; } } // All point are classified. Move the centroids to the // center of their respective cloud. displaced = 0; weighted_average = 0; total_weight = 0; for (n = 0; n < nb; ++n) { if (accum[n]) { const int new_center = (dist_accum[n] + accum[n] / 2) / accum[n]; displaced += abs(centers[n] - new_center); centers[n] = new_center; weighted_average += new_center * accum[n]; total_weight += accum[n]; } } weighted_average = (weighted_average + total_weight / 2) / total_weight; if (displaced < 5) break; // no need to keep on looping... } // Map each original value to the closest centroid for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { VP8MBInfo* const mb = &enc->mb_info_[n]; const int alpha = mb->alpha_; mb->segment_ = map[alpha]; mb->alpha_ = centers[map[alpha]]; // for the record. } if (nb > 1) { const int smooth = (enc->config_->preprocessing & 1); if (smooth) SmoothSegmentMap(enc); } SetSegmentAlphas(enc, centers, weighted_average); // pick some alphas. } //------------------------------------------------------------------------------ // Macroblock analysis: collect histogram for each mode, deduce the maximal // susceptibility and set best modes for this macroblock. // Segment assignment is done later. // Number of modes to inspect for alpha_ evaluation. For high-quality settings // (method >= FAST_ANALYSIS_METHOD) we don't need to test all the possible modes // during the analysis phase. #define FAST_ANALYSIS_METHOD 4 // method above which we do partial analysis #define MAX_INTRA16_MODE 2 #define MAX_INTRA4_MODE 2 #define MAX_UV_MODE 2 static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { const int max_mode = (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_INTRA16_MODE : NUM_PRED_MODES; int mode; int best_alpha = DEFAULT_ALPHA; int best_mode = 0; VP8MakeLuma16Preds(it); for (mode = 0; mode < max_mode; ++mode) { VP8Histogram histo = { { 0 } }; int alpha; VP8CollectHistogram(it->yuv_in_ + Y_OFF, it->yuv_p_ + VP8I16ModeOffsets[mode], 0, 16, &histo); alpha = GetAlpha(&histo); if (IS_BETTER_ALPHA(alpha, best_alpha)) { best_alpha = alpha; best_mode = mode; } } VP8SetIntra16Mode(it, best_mode); return best_alpha; } static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it, int best_alpha) { uint8_t modes[16]; const int max_mode = (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_INTRA4_MODE : NUM_BMODES; int i4_alpha; VP8Histogram total_histo = { { 0 } }; int cur_histo = 0; VP8IteratorStartI4(it); do { int mode; int best_mode_alpha = DEFAULT_ALPHA; VP8Histogram histos[2]; const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_]; VP8MakeIntra4Preds(it); for (mode = 0; mode < max_mode; ++mode) { int alpha; memset(&histos[cur_histo], 0, sizeof(histos[cur_histo])); VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode], 0, 1, &histos[cur_histo]); alpha = GetAlpha(&histos[cur_histo]); if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) { best_mode_alpha = alpha; modes[it->i4_] = mode; cur_histo ^= 1; // keep track of best histo so far. } } // accumulate best histogram MergeHistograms(&histos[cur_histo ^ 1], &total_histo); // Note: we reuse the original samples for predictors } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF)); i4_alpha = GetAlpha(&total_histo); if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) { VP8SetIntra4Mode(it, modes); best_alpha = i4_alpha; } return best_alpha; } static int MBAnalyzeBestUVMode(VP8EncIterator* const it) { int best_alpha = DEFAULT_ALPHA; int best_mode = 0; const int max_mode = (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_UV_MODE : NUM_PRED_MODES; int mode; VP8MakeChroma8Preds(it); for (mode = 0; mode < max_mode; ++mode) { VP8Histogram histo = { { 0 } }; int alpha; VP8CollectHistogram(it->yuv_in_ + U_OFF, it->yuv_p_ + VP8UVModeOffsets[mode], 16, 16 + 4 + 4, &histo); alpha = GetAlpha(&histo); if (IS_BETTER_ALPHA(alpha, best_alpha)) { best_alpha = alpha; best_mode = mode; } } VP8SetIntraUVMode(it, best_mode); return best_alpha; } static void MBAnalyze(VP8EncIterator* const it, int alphas[MAX_ALPHA + 1], int* const alpha, int* const uv_alpha) { const VP8Encoder* const enc = it->enc_; int best_alpha, best_uv_alpha; VP8SetIntra16Mode(it, 0); // default: Intra16, DC_PRED VP8SetSkip(it, 0); // not skipped VP8SetSegment(it, 0); // default segment, spec-wise. best_alpha = MBAnalyzeBestIntra16Mode(it); if (enc->method_ >= 5) { // We go and make a fast decision for intra4/intra16. // It's usually not a good and definitive pick, but helps seeding the stats // about level bit-cost. // TODO(skal): improve criterion. best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha); } best_uv_alpha = MBAnalyzeBestUVMode(it); // Final susceptibility mix best_alpha = (3 * best_alpha + best_uv_alpha + 2) >> 2; best_alpha = FinalAlphaValue(best_alpha); alphas[best_alpha]++; it->mb_->alpha_ = best_alpha; // for later remapping. // Accumulate for later complexity analysis. *alpha += best_alpha; // mixed susceptibility (not just luma) *uv_alpha += best_uv_alpha; } static void DefaultMBInfo(VP8MBInfo* const mb) { mb->type_ = 1; // I16x16 mb->uv_mode_ = 0; mb->skip_ = 0; // not skipped mb->segment_ = 0; // default segment mb->alpha_ = 0; } //------------------------------------------------------------------------------ // Main analysis loop: // Collect all susceptibilities for each macroblock and record their // distribution in alphas[]. Segments is assigned a-posteriori, based on // this histogram. // We also pick an intra16 prediction mode, which shouldn't be considered // final except for fast-encode settings. We can also pick some intra4 modes // and decide intra4/intra16, but that's usually almost always a bad choice at // this stage. static void ResetAllMBInfo(VP8Encoder* const enc) { int n; for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { DefaultMBInfo(&enc->mb_info_[n]); } // Default susceptibilities. enc->dqm_[0].alpha_ = 0; enc->dqm_[0].beta_ = 0; // Note: we can't compute this alpha_ / uv_alpha_ -> set to default value. enc->alpha_ = 0; enc->uv_alpha_ = 0; WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); } // struct used to collect job result typedef struct { WebPWorker worker; int alphas[MAX_ALPHA + 1]; int alpha, uv_alpha; VP8EncIterator it; int delta_progress; } SegmentJob; // main work call static int DoSegmentsJob(SegmentJob* const job, VP8EncIterator* const it) { int ok = 1; if (!VP8IteratorIsDone(it)) { uint8_t tmp[32 + ALIGN_CST]; uint8_t* const scratch = (uint8_t*)DO_ALIGN(tmp); do { // Let's pretend we have perfect lossless reconstruction. VP8IteratorImport(it, scratch); MBAnalyze(it, job->alphas, &job->alpha, &job->uv_alpha); ok = VP8IteratorProgress(it, job->delta_progress); } while (ok && VP8IteratorNext(it)); } return ok; } static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) { int i; for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i]; dst->alpha += src->alpha; dst->uv_alpha += src->uv_alpha; } // initialize the job struct with some TODOs static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job, int start_row, int end_row) { WebPWorkerInit(&job->worker); job->worker.data1 = job; job->worker.data2 = &job->it; job->worker.hook = (WebPWorkerHook)DoSegmentsJob; VP8IteratorInit(enc, &job->it); VP8IteratorSetRow(&job->it, start_row); VP8IteratorSetCountDown(&job->it, (end_row - start_row) * enc->mb_w_); memset(job->alphas, 0, sizeof(job->alphas)); job->alpha = 0; job->uv_alpha = 0; // only one of both jobs can record the progress, since we don't // expect the user's hook to be multi-thread safe job->delta_progress = (start_row == 0) ? 20 : 0; } // main entry point int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; const int do_segments = enc->config_->emulate_jpeg_size || // We need the complexity evaluation. (enc->segment_hdr_.num_segments_ > 1) || (enc->method_ == 0); // for method 0, we need preds_[] to be filled. if (do_segments) { const int last_row = enc->mb_h_; // We give a little more than a half work to the main thread. const int split_row = (9 * last_row + 15) >> 4; const int total_mb = last_row * enc->mb_w_; #ifdef WEBP_USE_THREAD const int kMinSplitRow = 2; // minimal rows needed for mt to be worth it const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow); #else const int do_mt = 0; #endif SegmentJob main_job; if (do_mt) { SegmentJob side_job; // Note the use of '&' instead of '&&' because we must call the functions // no matter what. InitSegmentJob(enc, &main_job, 0, split_row); InitSegmentJob(enc, &side_job, split_row, last_row); // we don't need to call Reset() on main_job.worker, since we're calling // WebPWorkerExecute() on it ok &= WebPWorkerReset(&side_job.worker); // launch the two jobs in parallel if (ok) { WebPWorkerLaunch(&side_job.worker); WebPWorkerExecute(&main_job.worker); ok &= WebPWorkerSync(&side_job.worker); ok &= WebPWorkerSync(&main_job.worker); } WebPWorkerEnd(&side_job.worker); if (ok) MergeJobs(&side_job, &main_job); // merge results together } else { // Even for single-thread case, we use the generic Worker tools. InitSegmentJob(enc, &main_job, 0, last_row); WebPWorkerExecute(&main_job.worker); ok &= WebPWorkerSync(&main_job.worker); } WebPWorkerEnd(&main_job.worker); if (ok) { enc->alpha_ = main_job.alpha / total_mb; enc->uv_alpha_ = main_job.uv_alpha / total_mb; AssignSegments(enc, main_job.alphas); } } else { // Use only one default segment. ResetAllMBInfo(enc); } return ok; } libwebp-0.4.0/src/enc/layer.c0000644000014400001440000000241612255002107012660 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Enhancement layer (for YUV444/422) // // Author: Skal (pascal.massimino@gmail.com) #include #include "./vp8enci.h" //------------------------------------------------------------------------------ void VP8EncInitLayer(VP8Encoder* const enc) { enc->use_layer_ = (enc->pic_->u0 != NULL); enc->layer_data_size_ = 0; enc->layer_data_ = NULL; if (enc->use_layer_) { VP8BitWriterInit(&enc->layer_bw_, enc->mb_w_ * enc->mb_h_ * 3); } } void VP8EncCodeLayerBlock(VP8EncIterator* it) { (void)it; // remove a warning } int VP8EncFinishLayer(VP8Encoder* const enc) { if (enc->use_layer_) { enc->layer_data_ = VP8BitWriterFinish(&enc->layer_bw_); enc->layer_data_size_ = VP8BitWriterSize(&enc->layer_bw_); } return 1; } void VP8EncDeleteLayer(VP8Encoder* enc) { free(enc->layer_data_); } libwebp-0.4.0/src/enc/iterator.c0000644000014400001440000003431312255002107013376 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // VP8Iterator: block iterator // // Author: Skal (pascal.massimino@gmail.com) #include #include "./vp8enci.h" //------------------------------------------------------------------------------ // VP8Iterator //------------------------------------------------------------------------------ static void InitLeft(VP8EncIterator* const it) { it->y_left_[-1] = it->u_left_[-1] = it->v_left_[-1] = (it->y_ > 0) ? 129 : 127; memset(it->y_left_, 129, 16); memset(it->u_left_, 129, 8); memset(it->v_left_, 129, 8); it->left_nz_[8] = 0; } static void InitTop(VP8EncIterator* const it) { const VP8Encoder* const enc = it->enc_; const size_t top_size = enc->mb_w_ * 16; memset(enc->y_top_, 127, 2 * top_size); memset(enc->nz_, 0, enc->mb_w_ * sizeof(*enc->nz_)); } void VP8IteratorSetRow(VP8EncIterator* const it, int y) { VP8Encoder* const enc = it->enc_; it->x_ = 0; it->y_ = y; it->bw_ = &enc->parts_[y & (enc->num_parts_ - 1)]; it->preds_ = enc->preds_ + y * 4 * enc->preds_w_; it->nz_ = enc->nz_; it->mb_ = enc->mb_info_ + y * enc->mb_w_; it->y_top_ = enc->y_top_; it->uv_top_ = enc->uv_top_; InitLeft(it); } void VP8IteratorReset(VP8EncIterator* const it) { VP8Encoder* const enc = it->enc_; VP8IteratorSetRow(it, 0); VP8IteratorSetCountDown(it, enc->mb_w_ * enc->mb_h_); // default InitTop(it); InitLeft(it); memset(it->bit_count_, 0, sizeof(it->bit_count_)); it->do_trellis_ = 0; } void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down) { it->count_down_ = it->count_down0_ = count_down; } int VP8IteratorIsDone(const VP8EncIterator* const it) { return (it->count_down_ <= 0); } void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it) { it->enc_ = enc; it->y_stride_ = enc->pic_->y_stride; it->uv_stride_ = enc->pic_->uv_stride; it->yuv_in_ = (uint8_t*)DO_ALIGN(it->yuv_mem_); it->yuv_out_ = it->yuv_in_ + YUV_SIZE; it->yuv_out2_ = it->yuv_out_ + YUV_SIZE; it->yuv_p_ = it->yuv_out2_ + YUV_SIZE; it->lf_stats_ = enc->lf_stats_; it->percent0_ = enc->percent_; it->y_left_ = (uint8_t*)DO_ALIGN(it->yuv_left_mem_ + 1); it->u_left_ = it->y_left_ + 16 + 16; it->v_left_ = it->u_left_ + 16; VP8IteratorReset(it); } int VP8IteratorProgress(const VP8EncIterator* const it, int delta) { VP8Encoder* const enc = it->enc_; if (delta && enc->pic_->progress_hook != NULL) { const int done = it->count_down0_ - it->count_down_; const int percent = (it->count_down0_ <= 0) ? it->percent0_ : it->percent0_ + delta * done / it->count_down0_; return WebPReportProgress(enc->pic_, percent, &enc->percent_); } return 1; } //------------------------------------------------------------------------------ // Import the source samples into the cache. Takes care of replicating // boundary pixels if necessary. static WEBP_INLINE int MinSize(int a, int b) { return (a < b) ? a : b; } static void ImportBlock(const uint8_t* src, int src_stride, uint8_t* dst, int w, int h, int size) { int i; for (i = 0; i < h; ++i) { memcpy(dst, src, w); if (w < size) { memset(dst + w, dst[w - 1], size - w); } dst += BPS; src += src_stride; } for (i = h; i < size; ++i) { memcpy(dst, dst - BPS, size); dst += BPS; } } static void ImportLine(const uint8_t* src, int src_stride, uint8_t* dst, int len, int total_len) { int i; for (i = 0; i < len; ++i, src += src_stride) dst[i] = *src; for (; i < total_len; ++i) dst[i] = dst[len - 1]; } void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32) { const VP8Encoder* const enc = it->enc_; const int x = it->x_, y = it->y_; const WebPPicture* const pic = enc->pic_; const uint8_t* const ysrc = pic->y + (y * pic->y_stride + x) * 16; const uint8_t* const usrc = pic->u + (y * pic->uv_stride + x) * 8; const uint8_t* const vsrc = pic->v + (y * pic->uv_stride + x) * 8; const int w = MinSize(pic->width - x * 16, 16); const int h = MinSize(pic->height - y * 16, 16); const int uv_w = (w + 1) >> 1; const int uv_h = (h + 1) >> 1; ImportBlock(ysrc, pic->y_stride, it->yuv_in_ + Y_OFF, w, h, 16); ImportBlock(usrc, pic->uv_stride, it->yuv_in_ + U_OFF, uv_w, uv_h, 8); ImportBlock(vsrc, pic->uv_stride, it->yuv_in_ + V_OFF, uv_w, uv_h, 8); if (tmp_32 == NULL) return; // Import source (uncompressed) samples into boundary. if (x == 0) { InitLeft(it); } else { if (y == 0) { it->y_left_[-1] = it->u_left_[-1] = it->v_left_[-1] = 127; } else { it->y_left_[-1] = ysrc[- 1 - pic->y_stride]; it->u_left_[-1] = usrc[- 1 - pic->uv_stride]; it->v_left_[-1] = vsrc[- 1 - pic->uv_stride]; } ImportLine(ysrc - 1, pic->y_stride, it->y_left_, h, 16); ImportLine(usrc - 1, pic->uv_stride, it->u_left_, uv_h, 8); ImportLine(vsrc - 1, pic->uv_stride, it->v_left_, uv_h, 8); } it->y_top_ = tmp_32 + 0; it->uv_top_ = tmp_32 + 16; if (y == 0) { memset(tmp_32, 127, 32 * sizeof(*tmp_32)); } else { ImportLine(ysrc - pic->y_stride, 1, tmp_32, w, 16); ImportLine(usrc - pic->uv_stride, 1, tmp_32 + 16, uv_w, 8); ImportLine(vsrc - pic->uv_stride, 1, tmp_32 + 16 + 8, uv_w, 8); } } //------------------------------------------------------------------------------ // Copy back the compressed samples into user space if requested. static void ExportBlock(const uint8_t* src, uint8_t* dst, int dst_stride, int w, int h) { while (h-- > 0) { memcpy(dst, src, w); dst += dst_stride; src += BPS; } } void VP8IteratorExport(const VP8EncIterator* const it) { const VP8Encoder* const enc = it->enc_; if (enc->config_->show_compressed) { const int x = it->x_, y = it->y_; const uint8_t* const ysrc = it->yuv_out_ + Y_OFF; const uint8_t* const usrc = it->yuv_out_ + U_OFF; const uint8_t* const vsrc = it->yuv_out_ + V_OFF; const WebPPicture* const pic = enc->pic_; uint8_t* const ydst = pic->y + (y * pic->y_stride + x) * 16; uint8_t* const udst = pic->u + (y * pic->uv_stride + x) * 8; uint8_t* const vdst = pic->v + (y * pic->uv_stride + x) * 8; int w = (pic->width - x * 16); int h = (pic->height - y * 16); if (w > 16) w = 16; if (h > 16) h = 16; // Luma plane ExportBlock(ysrc, ydst, pic->y_stride, w, h); { // U/V planes const int uv_w = (w + 1) >> 1; const int uv_h = (h + 1) >> 1; ExportBlock(usrc, udst, pic->uv_stride, uv_w, uv_h); ExportBlock(vsrc, vdst, pic->uv_stride, uv_w, uv_h); } } } //------------------------------------------------------------------------------ // Non-zero contexts setup/teardown // Nz bits: // 0 1 2 3 Y // 4 5 6 7 // 8 9 10 11 // 12 13 14 15 // 16 17 U // 18 19 // 20 21 V // 22 23 // 24 DC-intra16 // Convert packed context to byte array #define BIT(nz, n) (!!((nz) & (1 << (n)))) void VP8IteratorNzToBytes(VP8EncIterator* const it) { const int tnz = it->nz_[0], lnz = it->nz_[-1]; int* const top_nz = it->top_nz_; int* const left_nz = it->left_nz_; // Top-Y top_nz[0] = BIT(tnz, 12); top_nz[1] = BIT(tnz, 13); top_nz[2] = BIT(tnz, 14); top_nz[3] = BIT(tnz, 15); // Top-U top_nz[4] = BIT(tnz, 18); top_nz[5] = BIT(tnz, 19); // Top-V top_nz[6] = BIT(tnz, 22); top_nz[7] = BIT(tnz, 23); // DC top_nz[8] = BIT(tnz, 24); // left-Y left_nz[0] = BIT(lnz, 3); left_nz[1] = BIT(lnz, 7); left_nz[2] = BIT(lnz, 11); left_nz[3] = BIT(lnz, 15); // left-U left_nz[4] = BIT(lnz, 17); left_nz[5] = BIT(lnz, 19); // left-V left_nz[6] = BIT(lnz, 21); left_nz[7] = BIT(lnz, 23); // left-DC is special, iterated separately } void VP8IteratorBytesToNz(VP8EncIterator* const it) { uint32_t nz = 0; const int* const top_nz = it->top_nz_; const int* const left_nz = it->left_nz_; // top nz |= (top_nz[0] << 12) | (top_nz[1] << 13); nz |= (top_nz[2] << 14) | (top_nz[3] << 15); nz |= (top_nz[4] << 18) | (top_nz[5] << 19); nz |= (top_nz[6] << 22) | (top_nz[7] << 23); nz |= (top_nz[8] << 24); // we propagate the _top_ bit, esp. for intra4 // left nz |= (left_nz[0] << 3) | (left_nz[1] << 7); nz |= (left_nz[2] << 11); nz |= (left_nz[4] << 17) | (left_nz[6] << 21); *it->nz_ = nz; } #undef BIT //------------------------------------------------------------------------------ // Advance to the next position, doing the bookkeeping. void VP8IteratorSaveBoundary(VP8EncIterator* const it) { VP8Encoder* const enc = it->enc_; const int x = it->x_, y = it->y_; const uint8_t* const ysrc = it->yuv_out_ + Y_OFF; const uint8_t* const uvsrc = it->yuv_out_ + U_OFF; if (x < enc->mb_w_ - 1) { // left int i; for (i = 0; i < 16; ++i) { it->y_left_[i] = ysrc[15 + i * BPS]; } for (i = 0; i < 8; ++i) { it->u_left_[i] = uvsrc[7 + i * BPS]; it->v_left_[i] = uvsrc[15 + i * BPS]; } // top-left (before 'top'!) it->y_left_[-1] = it->y_top_[15]; it->u_left_[-1] = it->uv_top_[0 + 7]; it->v_left_[-1] = it->uv_top_[8 + 7]; } if (y < enc->mb_h_ - 1) { // top memcpy(it->y_top_, ysrc + 15 * BPS, 16); memcpy(it->uv_top_, uvsrc + 7 * BPS, 8 + 8); } } int VP8IteratorNext(VP8EncIterator* const it) { it->preds_ += 4; it->mb_ += 1; it->nz_ += 1; it->y_top_ += 16; it->uv_top_ += 16; it->x_ += 1; if (it->x_ == it->enc_->mb_w_) { VP8IteratorSetRow(it, ++it->y_); } return (0 < --it->count_down_); } //------------------------------------------------------------------------------ // Helper function to set mode properties void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode) { uint8_t* preds = it->preds_; int y; for (y = 0; y < 4; ++y) { memset(preds, mode, 4); preds += it->enc_->preds_w_; } it->mb_->type_ = 1; } void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes) { uint8_t* preds = it->preds_; int y; for (y = 4; y > 0; --y) { memcpy(preds, modes, 4 * sizeof(*modes)); preds += it->enc_->preds_w_; modes += 4; } it->mb_->type_ = 0; } void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode) { it->mb_->uv_mode_ = mode; } void VP8SetSkip(const VP8EncIterator* const it, int skip) { it->mb_->skip_ = skip; } void VP8SetSegment(const VP8EncIterator* const it, int segment) { it->mb_->segment_ = segment; } //------------------------------------------------------------------------------ // Intra4x4 sub-blocks iteration // // We store and update the boundary samples into an array of 37 pixels. They // are updated as we iterate and reconstructs each intra4x4 blocks in turn. // The position of the samples has the following snake pattern: // // 16|17 18 19 20|21 22 23 24|25 26 27 28|29 30 31 32|33 34 35 36 <- Top-right // --+-----------+-----------+-----------+-----------+ // 15| 19| 23| 27| 31| // 14| 18| 22| 26| 30| // 13| 17| 21| 25| 29| // 12|13 14 15 16|17 18 19 20|21 22 23 24|25 26 27 28| // --+-----------+-----------+-----------+-----------+ // 11| 15| 19| 23| 27| // 10| 14| 18| 22| 26| // 9| 13| 17| 21| 25| // 8| 9 10 11 12|13 14 15 16|17 18 19 20|21 22 23 24| // --+-----------+-----------+-----------+-----------+ // 7| 11| 15| 19| 23| // 6| 10| 14| 18| 22| // 5| 9| 13| 17| 21| // 4| 5 6 7 8| 9 10 11 12|13 14 15 16|17 18 19 20| // --+-----------+-----------+-----------+-----------+ // 3| 7| 11| 15| 19| // 2| 6| 10| 14| 18| // 1| 5| 9| 13| 17| // 0| 1 2 3 4| 5 6 7 8| 9 10 11 12|13 14 15 16| // --+-----------+-----------+-----------+-----------+ // Array to record the position of the top sample to pass to the prediction // functions in dsp.c. static const uint8_t VP8TopLeftI4[16] = { 17, 21, 25, 29, 13, 17, 21, 25, 9, 13, 17, 21, 5, 9, 13, 17 }; void VP8IteratorStartI4(VP8EncIterator* const it) { const VP8Encoder* const enc = it->enc_; int i; it->i4_ = 0; // first 4x4 sub-block it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[0]; // Import the boundary samples for (i = 0; i < 17; ++i) { // left it->i4_boundary_[i] = it->y_left_[15 - i]; } for (i = 0; i < 16; ++i) { // top it->i4_boundary_[17 + i] = it->y_top_[i]; } // top-right samples have a special case on the far right of the picture if (it->x_ < enc->mb_w_ - 1) { for (i = 16; i < 16 + 4; ++i) { it->i4_boundary_[17 + i] = it->y_top_[i]; } } else { // else, replicate the last valid pixel four times for (i = 16; i < 16 + 4; ++i) { it->i4_boundary_[17 + i] = it->i4_boundary_[17 + 15]; } } VP8IteratorNzToBytes(it); // import the non-zero context } int VP8IteratorRotateI4(VP8EncIterator* const it, const uint8_t* const yuv_out) { const uint8_t* const blk = yuv_out + VP8Scan[it->i4_]; uint8_t* const top = it->i4_top_; int i; // Update the cache with 7 fresh samples for (i = 0; i <= 3; ++i) { top[-4 + i] = blk[i + 3 * BPS]; // store future top samples } if ((it->i4_ & 3) != 3) { // if not on the right sub-blocks #3, #7, #11, #15 for (i = 0; i <= 2; ++i) { // store future left samples top[i] = blk[3 + (2 - i) * BPS]; } } else { // else replicate top-right samples, as says the specs. for (i = 0; i <= 3; ++i) { top[i] = top[i + 4]; } } // move pointers to next sub-block ++it->i4_; if (it->i4_ == 16) { // we're done return 0; } it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[it->i4_]; return 1; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/cost.c0000644000014400001440000006145412255002107012523 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Cost tables for level and modes // // Author: Skal (pascal.massimino@gmail.com) #include "./cost.h" //------------------------------------------------------------------------------ // Boolean-cost cost table const uint16_t VP8EntropyCost[256] = { 1792, 1792, 1792, 1536, 1536, 1408, 1366, 1280, 1280, 1216, 1178, 1152, 1110, 1076, 1061, 1024, 1024, 992, 968, 951, 939, 911, 896, 878, 871, 854, 838, 820, 811, 794, 786, 768, 768, 752, 740, 732, 720, 709, 704, 690, 683, 672, 666, 655, 647, 640, 631, 622, 615, 607, 598, 592, 586, 576, 572, 564, 559, 555, 547, 541, 534, 528, 522, 512, 512, 504, 500, 494, 488, 483, 477, 473, 467, 461, 458, 452, 448, 443, 438, 434, 427, 424, 419, 415, 410, 406, 403, 399, 394, 390, 384, 384, 377, 374, 370, 366, 362, 359, 355, 351, 347, 342, 342, 336, 333, 330, 326, 323, 320, 316, 312, 308, 305, 302, 299, 296, 293, 288, 287, 283, 280, 277, 274, 272, 268, 266, 262, 256, 256, 256, 251, 248, 245, 242, 240, 237, 234, 232, 228, 226, 223, 221, 218, 216, 214, 211, 208, 205, 203, 201, 198, 196, 192, 191, 188, 187, 183, 181, 179, 176, 175, 171, 171, 168, 165, 163, 160, 159, 156, 154, 152, 150, 148, 146, 144, 142, 139, 138, 135, 133, 131, 128, 128, 125, 123, 121, 119, 117, 115, 113, 111, 110, 107, 105, 103, 102, 100, 98, 96, 94, 92, 91, 89, 86, 86, 83, 82, 80, 77, 76, 74, 73, 71, 69, 67, 66, 64, 63, 61, 59, 57, 55, 54, 52, 51, 49, 47, 46, 44, 43, 41, 40, 38, 36, 35, 33, 32, 30, 29, 27, 25, 24, 22, 21, 19, 18, 16, 15, 13, 12, 10, 9, 7, 6, 4, 3 }; //------------------------------------------------------------------------------ // Level cost tables // For each given level, the following table gives the pattern of contexts to // use for coding it (in [][0]) as well as the bit value to use for each // context (in [][1]). const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2] = { {0x001, 0x000}, {0x007, 0x001}, {0x00f, 0x005}, {0x00f, 0x00d}, {0x033, 0x003}, {0x033, 0x003}, {0x033, 0x023}, {0x033, 0x023}, {0x033, 0x023}, {0x033, 0x023}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x153} }; // fixed costs for coding levels, deduce from the coding tree. // This is only the part that doesn't depend on the probability state. const uint16_t VP8LevelFixedCosts[MAX_LEVEL + 1] = { 0, 256, 256, 256, 256, 432, 618, 630, 731, 640, 640, 828, 901, 948, 1021, 1101, 1174, 1221, 1294, 1042, 1085, 1115, 1158, 1202, 1245, 1275, 1318, 1337, 1380, 1410, 1453, 1497, 1540, 1570, 1613, 1280, 1295, 1317, 1332, 1358, 1373, 1395, 1410, 1454, 1469, 1491, 1506, 1532, 1547, 1569, 1584, 1601, 1616, 1638, 1653, 1679, 1694, 1716, 1731, 1775, 1790, 1812, 1827, 1853, 1868, 1890, 1905, 1727, 1733, 1742, 1748, 1759, 1765, 1774, 1780, 1800, 1806, 1815, 1821, 1832, 1838, 1847, 1853, 1878, 1884, 1893, 1899, 1910, 1916, 1925, 1931, 1951, 1957, 1966, 1972, 1983, 1989, 1998, 2004, 2027, 2033, 2042, 2048, 2059, 2065, 2074, 2080, 2100, 2106, 2115, 2121, 2132, 2138, 2147, 2153, 2178, 2184, 2193, 2199, 2210, 2216, 2225, 2231, 2251, 2257, 2266, 2272, 2283, 2289, 2298, 2304, 2168, 2174, 2183, 2189, 2200, 2206, 2215, 2221, 2241, 2247, 2256, 2262, 2273, 2279, 2288, 2294, 2319, 2325, 2334, 2340, 2351, 2357, 2366, 2372, 2392, 2398, 2407, 2413, 2424, 2430, 2439, 2445, 2468, 2474, 2483, 2489, 2500, 2506, 2515, 2521, 2541, 2547, 2556, 2562, 2573, 2579, 2588, 2594, 2619, 2625, 2634, 2640, 2651, 2657, 2666, 2672, 2692, 2698, 2707, 2713, 2724, 2730, 2739, 2745, 2540, 2546, 2555, 2561, 2572, 2578, 2587, 2593, 2613, 2619, 2628, 2634, 2645, 2651, 2660, 2666, 2691, 2697, 2706, 2712, 2723, 2729, 2738, 2744, 2764, 2770, 2779, 2785, 2796, 2802, 2811, 2817, 2840, 2846, 2855, 2861, 2872, 2878, 2887, 2893, 2913, 2919, 2928, 2934, 2945, 2951, 2960, 2966, 2991, 2997, 3006, 3012, 3023, 3029, 3038, 3044, 3064, 3070, 3079, 3085, 3096, 3102, 3111, 3117, 2981, 2987, 2996, 3002, 3013, 3019, 3028, 3034, 3054, 3060, 3069, 3075, 3086, 3092, 3101, 3107, 3132, 3138, 3147, 3153, 3164, 3170, 3179, 3185, 3205, 3211, 3220, 3226, 3237, 3243, 3252, 3258, 3281, 3287, 3296, 3302, 3313, 3319, 3328, 3334, 3354, 3360, 3369, 3375, 3386, 3392, 3401, 3407, 3432, 3438, 3447, 3453, 3464, 3470, 3479, 3485, 3505, 3511, 3520, 3526, 3537, 3543, 3552, 3558, 2816, 2822, 2831, 2837, 2848, 2854, 2863, 2869, 2889, 2895, 2904, 2910, 2921, 2927, 2936, 2942, 2967, 2973, 2982, 2988, 2999, 3005, 3014, 3020, 3040, 3046, 3055, 3061, 3072, 3078, 3087, 3093, 3116, 3122, 3131, 3137, 3148, 3154, 3163, 3169, 3189, 3195, 3204, 3210, 3221, 3227, 3236, 3242, 3267, 3273, 3282, 3288, 3299, 3305, 3314, 3320, 3340, 3346, 3355, 3361, 3372, 3378, 3387, 3393, 3257, 3263, 3272, 3278, 3289, 3295, 3304, 3310, 3330, 3336, 3345, 3351, 3362, 3368, 3377, 3383, 3408, 3414, 3423, 3429, 3440, 3446, 3455, 3461, 3481, 3487, 3496, 3502, 3513, 3519, 3528, 3534, 3557, 3563, 3572, 3578, 3589, 3595, 3604, 3610, 3630, 3636, 3645, 3651, 3662, 3668, 3677, 3683, 3708, 3714, 3723, 3729, 3740, 3746, 3755, 3761, 3781, 3787, 3796, 3802, 3813, 3819, 3828, 3834, 3629, 3635, 3644, 3650, 3661, 3667, 3676, 3682, 3702, 3708, 3717, 3723, 3734, 3740, 3749, 3755, 3780, 3786, 3795, 3801, 3812, 3818, 3827, 3833, 3853, 3859, 3868, 3874, 3885, 3891, 3900, 3906, 3929, 3935, 3944, 3950, 3961, 3967, 3976, 3982, 4002, 4008, 4017, 4023, 4034, 4040, 4049, 4055, 4080, 4086, 4095, 4101, 4112, 4118, 4127, 4133, 4153, 4159, 4168, 4174, 4185, 4191, 4200, 4206, 4070, 4076, 4085, 4091, 4102, 4108, 4117, 4123, 4143, 4149, 4158, 4164, 4175, 4181, 4190, 4196, 4221, 4227, 4236, 4242, 4253, 4259, 4268, 4274, 4294, 4300, 4309, 4315, 4326, 4332, 4341, 4347, 4370, 4376, 4385, 4391, 4402, 4408, 4417, 4423, 4443, 4449, 4458, 4464, 4475, 4481, 4490, 4496, 4521, 4527, 4536, 4542, 4553, 4559, 4568, 4574, 4594, 4600, 4609, 4615, 4626, 4632, 4641, 4647, 3515, 3521, 3530, 3536, 3547, 3553, 3562, 3568, 3588, 3594, 3603, 3609, 3620, 3626, 3635, 3641, 3666, 3672, 3681, 3687, 3698, 3704, 3713, 3719, 3739, 3745, 3754, 3760, 3771, 3777, 3786, 3792, 3815, 3821, 3830, 3836, 3847, 3853, 3862, 3868, 3888, 3894, 3903, 3909, 3920, 3926, 3935, 3941, 3966, 3972, 3981, 3987, 3998, 4004, 4013, 4019, 4039, 4045, 4054, 4060, 4071, 4077, 4086, 4092, 3956, 3962, 3971, 3977, 3988, 3994, 4003, 4009, 4029, 4035, 4044, 4050, 4061, 4067, 4076, 4082, 4107, 4113, 4122, 4128, 4139, 4145, 4154, 4160, 4180, 4186, 4195, 4201, 4212, 4218, 4227, 4233, 4256, 4262, 4271, 4277, 4288, 4294, 4303, 4309, 4329, 4335, 4344, 4350, 4361, 4367, 4376, 4382, 4407, 4413, 4422, 4428, 4439, 4445, 4454, 4460, 4480, 4486, 4495, 4501, 4512, 4518, 4527, 4533, 4328, 4334, 4343, 4349, 4360, 4366, 4375, 4381, 4401, 4407, 4416, 4422, 4433, 4439, 4448, 4454, 4479, 4485, 4494, 4500, 4511, 4517, 4526, 4532, 4552, 4558, 4567, 4573, 4584, 4590, 4599, 4605, 4628, 4634, 4643, 4649, 4660, 4666, 4675, 4681, 4701, 4707, 4716, 4722, 4733, 4739, 4748, 4754, 4779, 4785, 4794, 4800, 4811, 4817, 4826, 4832, 4852, 4858, 4867, 4873, 4884, 4890, 4899, 4905, 4769, 4775, 4784, 4790, 4801, 4807, 4816, 4822, 4842, 4848, 4857, 4863, 4874, 4880, 4889, 4895, 4920, 4926, 4935, 4941, 4952, 4958, 4967, 4973, 4993, 4999, 5008, 5014, 5025, 5031, 5040, 5046, 5069, 5075, 5084, 5090, 5101, 5107, 5116, 5122, 5142, 5148, 5157, 5163, 5174, 5180, 5189, 5195, 5220, 5226, 5235, 5241, 5252, 5258, 5267, 5273, 5293, 5299, 5308, 5314, 5325, 5331, 5340, 5346, 4604, 4610, 4619, 4625, 4636, 4642, 4651, 4657, 4677, 4683, 4692, 4698, 4709, 4715, 4724, 4730, 4755, 4761, 4770, 4776, 4787, 4793, 4802, 4808, 4828, 4834, 4843, 4849, 4860, 4866, 4875, 4881, 4904, 4910, 4919, 4925, 4936, 4942, 4951, 4957, 4977, 4983, 4992, 4998, 5009, 5015, 5024, 5030, 5055, 5061, 5070, 5076, 5087, 5093, 5102, 5108, 5128, 5134, 5143, 5149, 5160, 5166, 5175, 5181, 5045, 5051, 5060, 5066, 5077, 5083, 5092, 5098, 5118, 5124, 5133, 5139, 5150, 5156, 5165, 5171, 5196, 5202, 5211, 5217, 5228, 5234, 5243, 5249, 5269, 5275, 5284, 5290, 5301, 5307, 5316, 5322, 5345, 5351, 5360, 5366, 5377, 5383, 5392, 5398, 5418, 5424, 5433, 5439, 5450, 5456, 5465, 5471, 5496, 5502, 5511, 5517, 5528, 5534, 5543, 5549, 5569, 5575, 5584, 5590, 5601, 5607, 5616, 5622, 5417, 5423, 5432, 5438, 5449, 5455, 5464, 5470, 5490, 5496, 5505, 5511, 5522, 5528, 5537, 5543, 5568, 5574, 5583, 5589, 5600, 5606, 5615, 5621, 5641, 5647, 5656, 5662, 5673, 5679, 5688, 5694, 5717, 5723, 5732, 5738, 5749, 5755, 5764, 5770, 5790, 5796, 5805, 5811, 5822, 5828, 5837, 5843, 5868, 5874, 5883, 5889, 5900, 5906, 5915, 5921, 5941, 5947, 5956, 5962, 5973, 5979, 5988, 5994, 5858, 5864, 5873, 5879, 5890, 5896, 5905, 5911, 5931, 5937, 5946, 5952, 5963, 5969, 5978, 5984, 6009, 6015, 6024, 6030, 6041, 6047, 6056, 6062, 6082, 6088, 6097, 6103, 6114, 6120, 6129, 6135, 6158, 6164, 6173, 6179, 6190, 6196, 6205, 6211, 6231, 6237, 6246, 6252, 6263, 6269, 6278, 6284, 6309, 6315, 6324, 6330, 6341, 6347, 6356, 6362, 6382, 6388, 6397, 6403, 6414, 6420, 6429, 6435, 3515, 3521, 3530, 3536, 3547, 3553, 3562, 3568, 3588, 3594, 3603, 3609, 3620, 3626, 3635, 3641, 3666, 3672, 3681, 3687, 3698, 3704, 3713, 3719, 3739, 3745, 3754, 3760, 3771, 3777, 3786, 3792, 3815, 3821, 3830, 3836, 3847, 3853, 3862, 3868, 3888, 3894, 3903, 3909, 3920, 3926, 3935, 3941, 3966, 3972, 3981, 3987, 3998, 4004, 4013, 4019, 4039, 4045, 4054, 4060, 4071, 4077, 4086, 4092, 3956, 3962, 3971, 3977, 3988, 3994, 4003, 4009, 4029, 4035, 4044, 4050, 4061, 4067, 4076, 4082, 4107, 4113, 4122, 4128, 4139, 4145, 4154, 4160, 4180, 4186, 4195, 4201, 4212, 4218, 4227, 4233, 4256, 4262, 4271, 4277, 4288, 4294, 4303, 4309, 4329, 4335, 4344, 4350, 4361, 4367, 4376, 4382, 4407, 4413, 4422, 4428, 4439, 4445, 4454, 4460, 4480, 4486, 4495, 4501, 4512, 4518, 4527, 4533, 4328, 4334, 4343, 4349, 4360, 4366, 4375, 4381, 4401, 4407, 4416, 4422, 4433, 4439, 4448, 4454, 4479, 4485, 4494, 4500, 4511, 4517, 4526, 4532, 4552, 4558, 4567, 4573, 4584, 4590, 4599, 4605, 4628, 4634, 4643, 4649, 4660, 4666, 4675, 4681, 4701, 4707, 4716, 4722, 4733, 4739, 4748, 4754, 4779, 4785, 4794, 4800, 4811, 4817, 4826, 4832, 4852, 4858, 4867, 4873, 4884, 4890, 4899, 4905, 4769, 4775, 4784, 4790, 4801, 4807, 4816, 4822, 4842, 4848, 4857, 4863, 4874, 4880, 4889, 4895, 4920, 4926, 4935, 4941, 4952, 4958, 4967, 4973, 4993, 4999, 5008, 5014, 5025, 5031, 5040, 5046, 5069, 5075, 5084, 5090, 5101, 5107, 5116, 5122, 5142, 5148, 5157, 5163, 5174, 5180, 5189, 5195, 5220, 5226, 5235, 5241, 5252, 5258, 5267, 5273, 5293, 5299, 5308, 5314, 5325, 5331, 5340, 5346, 4604, 4610, 4619, 4625, 4636, 4642, 4651, 4657, 4677, 4683, 4692, 4698, 4709, 4715, 4724, 4730, 4755, 4761, 4770, 4776, 4787, 4793, 4802, 4808, 4828, 4834, 4843, 4849, 4860, 4866, 4875, 4881, 4904, 4910, 4919, 4925, 4936, 4942, 4951, 4957, 4977, 4983, 4992, 4998, 5009, 5015, 5024, 5030, 5055, 5061, 5070, 5076, 5087, 5093, 5102, 5108, 5128, 5134, 5143, 5149, 5160, 5166, 5175, 5181, 5045, 5051, 5060, 5066, 5077, 5083, 5092, 5098, 5118, 5124, 5133, 5139, 5150, 5156, 5165, 5171, 5196, 5202, 5211, 5217, 5228, 5234, 5243, 5249, 5269, 5275, 5284, 5290, 5301, 5307, 5316, 5322, 5345, 5351, 5360, 5366, 5377, 5383, 5392, 5398, 5418, 5424, 5433, 5439, 5450, 5456, 5465, 5471, 5496, 5502, 5511, 5517, 5528, 5534, 5543, 5549, 5569, 5575, 5584, 5590, 5601, 5607, 5616, 5622, 5417, 5423, 5432, 5438, 5449, 5455, 5464, 5470, 5490, 5496, 5505, 5511, 5522, 5528, 5537, 5543, 5568, 5574, 5583, 5589, 5600, 5606, 5615, 5621, 5641, 5647, 5656, 5662, 5673, 5679, 5688, 5694, 5717, 5723, 5732, 5738, 5749, 5755, 5764, 5770, 5790, 5796, 5805, 5811, 5822, 5828, 5837, 5843, 5868, 5874, 5883, 5889, 5900, 5906, 5915, 5921, 5941, 5947, 5956, 5962, 5973, 5979, 5988, 5994, 5858, 5864, 5873, 5879, 5890, 5896, 5905, 5911, 5931, 5937, 5946, 5952, 5963, 5969, 5978, 5984, 6009, 6015, 6024, 6030, 6041, 6047, 6056, 6062, 6082, 6088, 6097, 6103, 6114, 6120, 6129, 6135, 6158, 6164, 6173, 6179, 6190, 6196, 6205, 6211, 6231, 6237, 6246, 6252, 6263, 6269, 6278, 6284, 6309, 6315, 6324, 6330, 6341, 6347, 6356, 6362, 6382, 6388, 6397, 6403, 6414, 6420, 6429, 6435, 5303, 5309, 5318, 5324, 5335, 5341, 5350, 5356, 5376, 5382, 5391, 5397, 5408, 5414, 5423, 5429, 5454, 5460, 5469, 5475, 5486, 5492, 5501, 5507, 5527, 5533, 5542, 5548, 5559, 5565, 5574, 5580, 5603, 5609, 5618, 5624, 5635, 5641, 5650, 5656, 5676, 5682, 5691, 5697, 5708, 5714, 5723, 5729, 5754, 5760, 5769, 5775, 5786, 5792, 5801, 5807, 5827, 5833, 5842, 5848, 5859, 5865, 5874, 5880, 5744, 5750, 5759, 5765, 5776, 5782, 5791, 5797, 5817, 5823, 5832, 5838, 5849, 5855, 5864, 5870, 5895, 5901, 5910, 5916, 5927, 5933, 5942, 5948, 5968, 5974, 5983, 5989, 6000, 6006, 6015, 6021, 6044, 6050, 6059, 6065, 6076, 6082, 6091, 6097, 6117, 6123, 6132, 6138, 6149, 6155, 6164, 6170, 6195, 6201, 6210, 6216, 6227, 6233, 6242, 6248, 6268, 6274, 6283, 6289, 6300, 6306, 6315, 6321, 6116, 6122, 6131, 6137, 6148, 6154, 6163, 6169, 6189, 6195, 6204, 6210, 6221, 6227, 6236, 6242, 6267, 6273, 6282, 6288, 6299, 6305, 6314, 6320, 6340, 6346, 6355, 6361, 6372, 6378, 6387, 6393, 6416, 6422, 6431, 6437, 6448, 6454, 6463, 6469, 6489, 6495, 6504, 6510, 6521, 6527, 6536, 6542, 6567, 6573, 6582, 6588, 6599, 6605, 6614, 6620, 6640, 6646, 6655, 6661, 6672, 6678, 6687, 6693, 6557, 6563, 6572, 6578, 6589, 6595, 6604, 6610, 6630, 6636, 6645, 6651, 6662, 6668, 6677, 6683, 6708, 6714, 6723, 6729, 6740, 6746, 6755, 6761, 6781, 6787, 6796, 6802, 6813, 6819, 6828, 6834, 6857, 6863, 6872, 6878, 6889, 6895, 6904, 6910, 6930, 6936, 6945, 6951, 6962, 6968, 6977, 6983, 7008, 7014, 7023, 7029, 7040, 7046, 7055, 7061, 7081, 7087, 7096, 7102, 7113, 7119, 7128, 7134, 6392, 6398, 6407, 6413, 6424, 6430, 6439, 6445, 6465, 6471, 6480, 6486, 6497, 6503, 6512, 6518, 6543, 6549, 6558, 6564, 6575, 6581, 6590, 6596, 6616, 6622, 6631, 6637, 6648, 6654, 6663, 6669, 6692, 6698, 6707, 6713, 6724, 6730, 6739, 6745, 6765, 6771, 6780, 6786, 6797, 6803, 6812, 6818, 6843, 6849, 6858, 6864, 6875, 6881, 6890, 6896, 6916, 6922, 6931, 6937, 6948, 6954, 6963, 6969, 6833, 6839, 6848, 6854, 6865, 6871, 6880, 6886, 6906, 6912, 6921, 6927, 6938, 6944, 6953, 6959, 6984, 6990, 6999, 7005, 7016, 7022, 7031, 7037, 7057, 7063, 7072, 7078, 7089, 7095, 7104, 7110, 7133, 7139, 7148, 7154, 7165, 7171, 7180, 7186, 7206, 7212, 7221, 7227, 7238, 7244, 7253, 7259, 7284, 7290, 7299, 7305, 7316, 7322, 7331, 7337, 7357, 7363, 7372, 7378, 7389, 7395, 7404, 7410, 7205, 7211, 7220, 7226, 7237, 7243, 7252, 7258, 7278, 7284, 7293, 7299, 7310, 7316, 7325, 7331, 7356, 7362, 7371, 7377, 7388, 7394, 7403, 7409, 7429, 7435, 7444, 7450, 7461, 7467, 7476, 7482, 7505, 7511, 7520, 7526, 7537, 7543, 7552, 7558, 7578, 7584, 7593, 7599, 7610, 7616, 7625, 7631, 7656, 7662, 7671, 7677, 7688, 7694, 7703, 7709, 7729, 7735, 7744, 7750, 7761 }; static int VariableLevelCost(int level, const uint8_t probas[NUM_PROBAS]) { int pattern = VP8LevelCodes[level - 1][0]; int bits = VP8LevelCodes[level - 1][1]; int cost = 0; int i; for (i = 2; pattern; ++i) { if (pattern & 1) { cost += VP8BitCost(bits & 1, probas[i]); } bits >>= 1; pattern >>= 1; } return cost; } //------------------------------------------------------------------------------ // Pre-calc level costs once for all void VP8CalculateLevelCosts(VP8Proba* const proba) { int ctype, band, ctx; if (!proba->dirty_) return; // nothing to do. for (ctype = 0; ctype < NUM_TYPES; ++ctype) { for (band = 0; band < NUM_BANDS; ++band) { for (ctx = 0; ctx < NUM_CTX; ++ctx) { const uint8_t* const p = proba->coeffs_[ctype][band][ctx]; uint16_t* const table = proba->level_cost_[ctype][band][ctx]; const int cost_base = VP8BitCost(1, p[1]); int v; table[0] = VP8BitCost(0, p[1]); for (v = 1; v <= MAX_VARIABLE_LEVEL; ++v) { table[v] = cost_base + VariableLevelCost(v, p); } // Starting at level 67 and up, the variable part of the cost is // actually constant. } } } proba->dirty_ = 0; } //------------------------------------------------------------------------------ // Mode cost tables. // These are the fixed probabilities (in the coding trees) turned into bit-cost // by calling VP8BitCost(). const uint16_t VP8FixedCostsUV[4] = { 302, 984, 439, 642 }; // note: these values include the fixed VP8BitCost(1, 145) mode selection cost. const uint16_t VP8FixedCostsI16[4] = { 663, 919, 872, 919 }; const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES] = { { { 40, 1151, 1723, 1874, 2103, 2019, 1628, 1777, 2226, 2137 }, { 192, 469, 1296, 1308, 1849, 1794, 1781, 1703, 1713, 1522 }, { 142, 910, 762, 1684, 1849, 1576, 1460, 1305, 1801, 1657 }, { 559, 641, 1370, 421, 1182, 1569, 1612, 1725, 863, 1007 }, { 299, 1059, 1256, 1108, 636, 1068, 1581, 1883, 869, 1142 }, { 277, 1111, 707, 1362, 1089, 672, 1603, 1541, 1545, 1291 }, { 214, 781, 1609, 1303, 1632, 2229, 726, 1560, 1713, 918 }, { 152, 1037, 1046, 1759, 1983, 2174, 1358, 742, 1740, 1390 }, { 512, 1046, 1420, 753, 752, 1297, 1486, 1613, 460, 1207 }, { 424, 827, 1362, 719, 1462, 1202, 1199, 1476, 1199, 538 } }, { { 240, 402, 1134, 1491, 1659, 1505, 1517, 1555, 1979, 2099 }, { 467, 242, 960, 1232, 1714, 1620, 1834, 1570, 1676, 1391 }, { 500, 455, 463, 1507, 1699, 1282, 1564, 982, 2114, 2114 }, { 672, 643, 1372, 331, 1589, 1667, 1453, 1938, 996, 876 }, { 458, 783, 1037, 911, 738, 968, 1165, 1518, 859, 1033 }, { 504, 815, 504, 1139, 1219, 719, 1506, 1085, 1268, 1268 }, { 333, 630, 1445, 1239, 1883, 3672, 799, 1548, 1865, 598 }, { 399, 644, 746, 1342, 1856, 1350, 1493, 613, 1855, 1015 }, { 622, 749, 1205, 608, 1066, 1408, 1290, 1406, 546, 971 }, { 500, 753, 1041, 668, 1230, 1617, 1297, 1425, 1383, 523 } }, { { 394, 553, 523, 1502, 1536, 981, 1608, 1142, 1666, 2181 }, { 655, 430, 375, 1411, 1861, 1220, 1677, 1135, 1978, 1553 }, { 690, 640, 245, 1954, 2070, 1194, 1528, 982, 1972, 2232 }, { 559, 834, 741, 867, 1131, 980, 1225, 852, 1092, 784 }, { 690, 875, 516, 959, 673, 894, 1056, 1190, 1528, 1126 }, { 740, 951, 384, 1277, 1177, 492, 1579, 1155, 1846, 1513 }, { 323, 775, 1062, 1776, 3062, 1274, 813, 1188, 1372, 655 }, { 488, 971, 484, 1767, 1515, 1775, 1115, 503, 1539, 1461 }, { 740, 1006, 998, 709, 851, 1230, 1337, 788, 741, 721 }, { 522, 1073, 573, 1045, 1346, 887, 1046, 1146, 1203, 697 } }, { { 105, 864, 1442, 1009, 1934, 1840, 1519, 1920, 1673, 1579 }, { 534, 305, 1193, 683, 1388, 2164, 1802, 1894, 1264, 1170 }, { 305, 518, 877, 1108, 1426, 3215, 1425, 1064, 1320, 1242 }, { 683, 732, 1927, 257, 1493, 2048, 1858, 1552, 1055, 947 }, { 394, 814, 1024, 660, 959, 1556, 1282, 1289, 893, 1047 }, { 528, 615, 996, 940, 1201, 635, 1094, 2515, 803, 1358 }, { 347, 614, 1609, 1187, 3133, 1345, 1007, 1339, 1017, 667 }, { 218, 740, 878, 1605, 3650, 3650, 1345, 758, 1357, 1617 }, { 672, 750, 1541, 558, 1257, 1599, 1870, 2135, 402, 1087 }, { 592, 684, 1161, 430, 1092, 1497, 1475, 1489, 1095, 822 } }, { { 228, 1056, 1059, 1368, 752, 982, 1512, 1518, 987, 1782 }, { 494, 514, 818, 942, 965, 892, 1610, 1356, 1048, 1363 }, { 512, 648, 591, 1042, 761, 991, 1196, 1454, 1309, 1463 }, { 683, 749, 1043, 676, 841, 1396, 1133, 1138, 654, 939 }, { 622, 1101, 1126, 994, 361, 1077, 1203, 1318, 877, 1219 }, { 631, 1068, 857, 1650, 651, 477, 1650, 1419, 828, 1170 }, { 555, 727, 1068, 1335, 3127, 1339, 820, 1331, 1077, 429 }, { 504, 879, 624, 1398, 889, 889, 1392, 808, 891, 1406 }, { 683, 1602, 1289, 977, 578, 983, 1280, 1708, 406, 1122 }, { 399, 865, 1433, 1070, 1072, 764, 968, 1477, 1223, 678 } }, { { 333, 760, 935, 1638, 1010, 529, 1646, 1410, 1472, 2219 }, { 512, 494, 750, 1160, 1215, 610, 1870, 1868, 1628, 1169 }, { 572, 646, 492, 1934, 1208, 603, 1580, 1099, 1398, 1995 }, { 786, 789, 942, 581, 1018, 951, 1599, 1207, 731, 768 }, { 690, 1015, 672, 1078, 582, 504, 1693, 1438, 1108, 2897 }, { 768, 1267, 571, 2005, 1243, 244, 2881, 1380, 1786, 1453 }, { 452, 899, 1293, 903, 1311, 3100, 465, 1311, 1319, 813 }, { 394, 927, 942, 1103, 1358, 1104, 946, 593, 1363, 1109 }, { 559, 1005, 1007, 1016, 658, 1173, 1021, 1164, 623, 1028 }, { 564, 796, 632, 1005, 1014, 863, 2316, 1268, 938, 764 } }, { { 266, 606, 1098, 1228, 1497, 1243, 948, 1030, 1734, 1461 }, { 366, 585, 901, 1060, 1407, 1247, 876, 1134, 1620, 1054 }, { 452, 565, 542, 1729, 1479, 1479, 1016, 886, 2938, 1150 }, { 555, 1088, 1533, 950, 1354, 895, 834, 1019, 1021, 496 }, { 704, 815, 1193, 971, 973, 640, 1217, 2214, 832, 578 }, { 672, 1245, 579, 871, 875, 774, 872, 1273, 1027, 949 }, { 296, 1134, 2050, 1784, 1636, 3425, 442, 1550, 2076, 722 }, { 342, 982, 1259, 1846, 1848, 1848, 622, 568, 1847, 1052 }, { 555, 1064, 1304, 828, 746, 1343, 1075, 1329, 1078, 494 }, { 288, 1167, 1285, 1174, 1639, 1639, 833, 2254, 1304, 509 } }, { { 342, 719, 767, 1866, 1757, 1270, 1246, 550, 1746, 2151 }, { 483, 653, 694, 1509, 1459, 1410, 1218, 507, 1914, 1266 }, { 488, 757, 447, 2979, 1813, 1268, 1654, 539, 1849, 2109 }, { 522, 1097, 1085, 851, 1365, 1111, 851, 901, 961, 605 }, { 709, 716, 841, 728, 736, 945, 941, 862, 2845, 1057 }, { 512, 1323, 500, 1336, 1083, 681, 1342, 717, 1604, 1350 }, { 452, 1155, 1372, 1900, 1501, 3290, 311, 944, 1919, 922 }, { 403, 1520, 977, 2132, 1733, 3522, 1076, 276, 3335, 1547 }, { 559, 1374, 1101, 615, 673, 2462, 974, 795, 984, 984 }, { 547, 1122, 1062, 812, 1410, 951, 1140, 622, 1268, 651 } }, { { 165, 982, 1235, 938, 1334, 1366, 1659, 1578, 964, 1612 }, { 592, 422, 925, 847, 1139, 1112, 1387, 2036, 861, 1041 }, { 403, 837, 732, 770, 941, 1658, 1250, 809, 1407, 1407 }, { 896, 874, 1071, 381, 1568, 1722, 1437, 2192, 480, 1035 }, { 640, 1098, 1012, 1032, 684, 1382, 1581, 2106, 416, 865 }, { 559, 1005, 819, 914, 710, 770, 1418, 920, 838, 1435 }, { 415, 1258, 1245, 870, 1278, 3067, 770, 1021, 1287, 522 }, { 406, 990, 601, 1009, 1265, 1265, 1267, 759, 1017, 1277 }, { 968, 1182, 1329, 788, 1032, 1292, 1705, 1714, 203, 1403 }, { 732, 877, 1279, 471, 901, 1161, 1545, 1294, 755, 755 } }, { { 111, 931, 1378, 1185, 1933, 1648, 1148, 1714, 1873, 1307 }, { 406, 414, 1030, 1023, 1910, 1404, 1313, 1647, 1509, 793 }, { 342, 640, 575, 1088, 1241, 1349, 1161, 1350, 1756, 1502 }, { 559, 766, 1185, 357, 1682, 1428, 1329, 1897, 1219, 802 }, { 473, 909, 1164, 771, 719, 2508, 1427, 1432, 722, 782 }, { 342, 892, 785, 1145, 1150, 794, 1296, 1550, 973, 1057 }, { 208, 1036, 1326, 1343, 1606, 3395, 815, 1455, 1618, 712 }, { 228, 928, 890, 1046, 3499, 1711, 994, 829, 1720, 1318 }, { 768, 724, 1058, 636, 991, 1075, 1319, 1324, 616, 825 }, { 305, 1167, 1358, 899, 1587, 1587, 987, 1988, 1332, 501 } } }; //------------------------------------------------------------------------------ libwebp-0.4.0/src/enc/Makefile.am0000644000014400001440000000215612255002107013435 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebpencode.la libwebpencode_la_SOURCES = libwebpencode_la_SOURCES += alpha.c libwebpencode_la_SOURCES += analysis.c libwebpencode_la_SOURCES += backward_references.c libwebpencode_la_SOURCES += config.c libwebpencode_la_SOURCES += cost.c libwebpencode_la_SOURCES += cost.h libwebpencode_la_SOURCES += filter.c libwebpencode_la_SOURCES += frame.c libwebpencode_la_SOURCES += histogram.c libwebpencode_la_SOURCES += iterator.c libwebpencode_la_SOURCES += layer.c libwebpencode_la_SOURCES += picture.c libwebpencode_la_SOURCES += quant.c libwebpencode_la_SOURCES += syntax.c libwebpencode_la_SOURCES += token.c libwebpencode_la_SOURCES += tree.c libwebpencode_la_SOURCES += vp8enci.h libwebpencode_la_SOURCES += vp8l.c libwebpencode_la_SOURCES += webpenc.c libwebpencodeinclude_HEADERS = libwebpencodeinclude_HEADERS += ../webp/encode.h libwebpencodeinclude_HEADERS += ../webp/types.h noinst_HEADERS = noinst_HEADERS += ../webp/format_constants.h libwebpencode_la_LDFLAGS = -lm libwebpencode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) libwebpencodeincludedir = $(includedir)/webp libwebp-0.4.0/src/enc/token.c0000644000014400001440000001774612255002107012700 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Paginated token buffer // // A 'token' is a bit value associated with a probability, either fixed // or a later-to-be-determined after statistics have been collected. // For dynamic probability, we just record the slot id (idx) for the probability // value in the final probability array (uint8_t* probas in VP8EmitTokens). // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #include "./cost.h" #include "./vp8enci.h" #if !defined(DISABLE_TOKEN_BUFFER) // we use pages to reduce the number of memcpy() #define MAX_NUM_TOKEN 8192 // max number of token per page #define FIXED_PROBA_BIT (1u << 14) struct VP8Tokens { uint16_t tokens_[MAX_NUM_TOKEN]; // bit#15: bit // bit #14: constant proba or idx // bits 0..13: slot or constant proba VP8Tokens* next_; }; //------------------------------------------------------------------------------ void VP8TBufferInit(VP8TBuffer* const b) { b->tokens_ = NULL; b->pages_ = NULL; b->last_page_ = &b->pages_; b->left_ = 0; b->error_ = 0; } void VP8TBufferClear(VP8TBuffer* const b) { if (b != NULL) { const VP8Tokens* p = b->pages_; while (p != NULL) { const VP8Tokens* const next = p->next_; free((void*)p); p = next; } VP8TBufferInit(b); } } static int TBufferNewPage(VP8TBuffer* const b) { VP8Tokens* const page = b->error_ ? NULL : (VP8Tokens*)malloc(sizeof(*page)); if (page == NULL) { b->error_ = 1; return 0; } *b->last_page_ = page; b->last_page_ = &page->next_; b->left_ = MAX_NUM_TOKEN; b->tokens_ = page->tokens_; page->next_ = NULL; return 1; } //------------------------------------------------------------------------------ #define TOKEN_ID(t, b, ctx, p) \ ((p) + NUM_PROBAS * ((ctx) + NUM_CTX * ((b) + NUM_BANDS * (t)))) static WEBP_INLINE int AddToken(VP8TBuffer* const b, int bit, uint32_t proba_idx) { assert(proba_idx < FIXED_PROBA_BIT); assert(bit == 0 || bit == 1); if (b->left_ > 0 || TBufferNewPage(b)) { const int slot = --b->left_; b->tokens_[slot] = (bit << 15) | proba_idx; } return bit; } static WEBP_INLINE void AddConstantToken(VP8TBuffer* const b, int bit, int proba) { assert(proba < 256); assert(bit == 0 || bit == 1); if (b->left_ > 0 || TBufferNewPage(b)) { const int slot = --b->left_; b->tokens_[slot] = (bit << 15) | FIXED_PROBA_BIT | proba; } } int VP8RecordCoeffTokens(int ctx, int coeff_type, int first, int last, const int16_t* const coeffs, VP8TBuffer* const tokens) { int n = first; uint32_t base_id = TOKEN_ID(coeff_type, n, ctx, 0); if (!AddToken(tokens, last >= 0, base_id + 0)) { return 0; } while (n < 16) { const int c = coeffs[n++]; const int sign = c < 0; int v = sign ? -c : c; if (!AddToken(tokens, v != 0, base_id + 1)) { ctx = 0; base_id = TOKEN_ID(coeff_type, VP8EncBands[n], ctx, 0); continue; } if (!AddToken(tokens, v > 1, base_id + 2)) { ctx = 1; } else { if (!AddToken(tokens, v > 4, base_id + 3)) { if (AddToken(tokens, v != 2, base_id + 4)) AddToken(tokens, v == 4, base_id + 5); } else if (!AddToken(tokens, v > 10, base_id + 6)) { if (!AddToken(tokens, v > 6, base_id + 7)) { AddConstantToken(tokens, v == 6, 159); } else { AddConstantToken(tokens, v >= 9, 165); AddConstantToken(tokens, !(v & 1), 145); } } else { int mask; const uint8_t* tab; if (v < 3 + (8 << 1)) { // VP8Cat3 (3b) AddToken(tokens, 0, base_id + 8); AddToken(tokens, 0, base_id + 9); v -= 3 + (8 << 0); mask = 1 << 2; tab = VP8Cat3; } else if (v < 3 + (8 << 2)) { // VP8Cat4 (4b) AddToken(tokens, 0, base_id + 8); AddToken(tokens, 1, base_id + 9); v -= 3 + (8 << 1); mask = 1 << 3; tab = VP8Cat4; } else if (v < 3 + (8 << 3)) { // VP8Cat5 (5b) AddToken(tokens, 1, base_id + 8); AddToken(tokens, 0, base_id + 10); v -= 3 + (8 << 2); mask = 1 << 4; tab = VP8Cat5; } else { // VP8Cat6 (11b) AddToken(tokens, 1, base_id + 8); AddToken(tokens, 1, base_id + 10); v -= 3 + (8 << 3); mask = 1 << 10; tab = VP8Cat6; } while (mask) { AddConstantToken(tokens, !!(v & mask), *tab++); mask >>= 1; } } ctx = 2; } AddConstantToken(tokens, sign, 128); base_id = TOKEN_ID(coeff_type, VP8EncBands[n], ctx, 0); if (n == 16 || !AddToken(tokens, n <= last, base_id + 0)) { return 1; // EOB } } return 1; } #undef TOKEN_ID //------------------------------------------------------------------------------ // This function works, but isn't currently used. Saved for later. #if 0 static void Record(int bit, proba_t* const stats) { proba_t p = *stats; if (p >= 0xffff0000u) { // an overflow is inbound. p = ((p + 1u) >> 1) & 0x7fff7fffu; // -> divide the stats by 2. } // record bit count (lower 16 bits) and increment total count (upper 16 bits). p += 0x00010000u + bit; *stats = p; } void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats) { const VP8Tokens* p = b->pages_; while (p != NULL) { const int N = (p->next_ == NULL) ? b->left_ : 0; int n = MAX_NUM_TOKEN; while (n-- > N) { const uint16_t token = p->tokens_[n]; if (!(token & FIXED_PROBA_BIT)) { Record((token >> 15) & 1, stats + (token & 0x3fffu)); } } p = p->next_; } } #endif // 0 //------------------------------------------------------------------------------ // Final coding pass, with known probabilities int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw, const uint8_t* const probas, int final_pass) { const VP8Tokens* p = b->pages_; (void)final_pass; if (b->error_) return 0; while (p != NULL) { const VP8Tokens* const next = p->next_; const int N = (next == NULL) ? b->left_ : 0; int n = MAX_NUM_TOKEN; while (n-- > N) { const uint16_t token = p->tokens_[n]; const int bit = (token >> 15) & 1; if (token & FIXED_PROBA_BIT) { VP8PutBit(bw, bit, token & 0xffu); // constant proba } else { VP8PutBit(bw, bit, probas[token & 0x3fffu]); } } if (final_pass) free((void*)p); p = next; } if (final_pass) b->pages_ = NULL; return 1; } // Size estimation size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas) { size_t size = 0; const VP8Tokens* p = b->pages_; if (b->error_) return 0; while (p != NULL) { const VP8Tokens* const next = p->next_; const int N = (next == NULL) ? b->left_ : 0; int n = MAX_NUM_TOKEN; while (n-- > N) { const uint16_t token = p->tokens_[n]; const int bit = token & (1 << 15); if (token & FIXED_PROBA_BIT) { size += VP8BitCost(bit, token & 0xffu); } else { size += VP8BitCost(bit, probas[token & 0x3fffu]); } } p = next; } return size; } //------------------------------------------------------------------------------ #else // DISABLE_TOKEN_BUFFER void VP8TBufferInit(VP8TBuffer* const b) { (void)b; } void VP8TBufferClear(VP8TBuffer* const b) { (void)b; } #endif // !DISABLE_TOKEN_BUFFER libwebp-0.4.0/src/dec/0000755000014400001440000000000012255206714011375 5ustar libwebp-0.4.0/src/dec/decode_vp8.h0000644000014400001440000001553312255002107013563 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Low-level API for VP8 decoder // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_DECODE_VP8_H_ #define WEBP_WEBP_DECODE_VP8_H_ #include "../webp/decode.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Lower-level API // // These functions provide fine-grained control of the decoding process. // The call flow should resemble: // // VP8Io io; // VP8InitIo(&io); // io.data = data; // io.data_size = size; // /* customize io's functions (setup()/put()/teardown()) if needed. */ // // VP8Decoder* dec = VP8New(); // bool ok = VP8Decode(dec); // if (!ok) printf("Error: %s\n", VP8StatusMessage(dec)); // VP8Delete(dec); // return ok; // Input / Output typedef struct VP8Io VP8Io; typedef int (*VP8IoPutHook)(const VP8Io* io); typedef int (*VP8IoSetupHook)(VP8Io* io); typedef void (*VP8IoTeardownHook)(const VP8Io* io); struct VP8Io { // set by VP8GetHeaders() int width, height; // picture dimensions, in pixels (invariable). // These are the original, uncropped dimensions. // The actual area passed to put() is stored // in mb_w / mb_h fields. // set before calling put() int mb_y; // position of the current rows (in pixels) int mb_w; // number of columns in the sample int mb_h; // number of rows in the sample const uint8_t* y, *u, *v; // rows to copy (in yuv420 format) int y_stride; // row stride for luma int uv_stride; // row stride for chroma void* opaque; // user data // called when fresh samples are available. Currently, samples are in // YUV420 format, and can be up to width x 24 in size (depending on the // in-loop filtering level, e.g.). Should return false in case of error // or abort request. The actual size of the area to update is mb_w x mb_h // in size, taking cropping into account. VP8IoPutHook put; // called just before starting to decode the blocks. // Must return false in case of setup error, true otherwise. If false is // returned, teardown() will NOT be called. But if the setup succeeded // and true is returned, then teardown() will always be called afterward. VP8IoSetupHook setup; // Called just after block decoding is finished (or when an error occurred // during put()). Is NOT called if setup() failed. VP8IoTeardownHook teardown; // this is a recommendation for the user-side yuv->rgb converter. This flag // is set when calling setup() hook and can be overwritten by it. It then // can be taken into consideration during the put() method. int fancy_upsampling; // Input buffer. size_t data_size; const uint8_t* data; // If true, in-loop filtering will not be performed even if present in the // bitstream. Switching off filtering may speed up decoding at the expense // of more visible blocking. Note that output will also be non-compliant // with the VP8 specifications. int bypass_filtering; // Cropping parameters. int use_cropping; int crop_left, crop_right, crop_top, crop_bottom; // Scaling parameters. int use_scaling; int scaled_width, scaled_height; // If non NULL, pointer to the alpha data (if present) corresponding to the // start of the current row (That is: it is pre-offset by mb_y and takes // cropping into account). const uint8_t* a; }; // Internal, version-checked, entry point int VP8InitIoInternal(VP8Io* const, int); // Set the custom IO function pointers and user-data. The setter for IO hooks // should be called before initiating incremental decoding. Returns true if // WebPIDecoder object is successfully modified, false otherwise. int WebPISetIOHooks(WebPIDecoder* const idec, VP8IoPutHook put, VP8IoSetupHook setup, VP8IoTeardownHook teardown, void* user_data); // Main decoding object. This is an opaque structure. typedef struct VP8Decoder VP8Decoder; // Create a new decoder object. VP8Decoder* VP8New(void); // Must be called to make sure 'io' is initialized properly. // Returns false in case of version mismatch. Upon such failure, no other // decoding function should be called (VP8Decode, VP8GetHeaders, ...) static WEBP_INLINE int VP8InitIo(VP8Io* const io) { return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION); } // Decode the VP8 frame header. Returns true if ok. // Note: 'io->data' must be pointing to the start of the VP8 frame header. int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io); // Decode a picture. Will call VP8GetHeaders() if it wasn't done already. // Returns false in case of error. int VP8Decode(VP8Decoder* const dec, VP8Io* const io); // Return current status of the decoder: VP8StatusCode VP8Status(VP8Decoder* const dec); // return readable string corresponding to the last status. const char* VP8StatusMessage(VP8Decoder* const dec); // Resets the decoder in its initial state, reclaiming memory. // Not a mandatory call between calls to VP8Decode(). void VP8Clear(VP8Decoder* const dec); // Destroy the decoder object. void VP8Delete(VP8Decoder* const dec); //------------------------------------------------------------------------------ // Miscellaneous VP8/VP8L bitstream probing functions. // Returns true if the next 3 bytes in data contain the VP8 signature. WEBP_EXTERN(int) VP8CheckSignature(const uint8_t* const data, size_t data_size); // Validates the VP8 data-header and retrieves basic header information viz // width and height. Returns 0 in case of formatting error. *width/*height // can be passed NULL. WEBP_EXTERN(int) VP8GetInfo( const uint8_t* data, size_t data_size, // data available so far size_t chunk_size, // total data size expected in the chunk int* const width, int* const height); // Returns true if the next byte(s) in data is a VP8L signature. WEBP_EXTERN(int) VP8LCheckSignature(const uint8_t* const data, size_t size); // Validates the VP8L data-header and retrieves basic header information viz // width, height and alpha. Returns 0 in case of formatting error. // width/height/has_alpha can be passed NULL. WEBP_EXTERN(int) VP8LGetInfo( const uint8_t* data, size_t data_size, // data available so far int* const width, int* const height, int* const has_alpha); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_DECODE_VP8_H_ */ libwebp-0.4.0/src/dec/alpha.c0000644000014400001440000001215112255002107012614 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Alpha-plane decompression. // // Author: Skal (pascal.massimino@gmail.com) #include #include "./alphai.h" #include "./vp8i.h" #include "./vp8li.h" #include "../utils/quant_levels_dec.h" #include "../webp/format_constants.h" //------------------------------------------------------------------------------ // ALPHDecoder object. ALPHDecoder* ALPHNew(void) { ALPHDecoder* const dec = (ALPHDecoder*)calloc(1, sizeof(*dec)); return dec; } void ALPHDelete(ALPHDecoder* const dec) { if (dec != NULL) { VP8LDelete(dec->vp8l_dec_); dec->vp8l_dec_ = NULL; free(dec); } } //------------------------------------------------------------------------------ // Decoding. // Initialize alpha decoding by parsing the alpha header and decoding the image // header for alpha data stored using lossless compression. // Returns false in case of error in alpha header (data too short, invalid // compression method or filter, error in lossless header data etc). static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data, size_t data_size, int width, int height, uint8_t* output) { int ok = 0; const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN; const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN; int rsrv; assert(width > 0 && height > 0); assert(data != NULL && output != NULL); dec->width_ = width; dec->height_ = height; if (data_size <= ALPHA_HEADER_LEN) { return 0; } dec->method_ = (data[0] >> 0) & 0x03; dec->filter_ = (data[0] >> 2) & 0x03; dec->pre_processing_ = (data[0] >> 4) & 0x03; rsrv = (data[0] >> 6) & 0x03; if (dec->method_ < ALPHA_NO_COMPRESSION || dec->method_ > ALPHA_LOSSLESS_COMPRESSION || dec->filter_ >= WEBP_FILTER_LAST || dec->pre_processing_ > ALPHA_PREPROCESSED_LEVELS || rsrv != 0) { return 0; } if (dec->method_ == ALPHA_NO_COMPRESSION) { const size_t alpha_decoded_size = dec->width_ * dec->height_; ok = (alpha_data_size >= alpha_decoded_size); } else { assert(dec->method_ == ALPHA_LOSSLESS_COMPRESSION); ok = VP8LDecodeAlphaHeader(dec, alpha_data, alpha_data_size, output); } return ok; } // Decodes, unfilters and dequantizes *at least* 'num_rows' rows of alpha // starting from row number 'row'. It assumes that rows up to (row - 1) have // already been decoded. // Returns false in case of bitstream error. static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) { ALPHDecoder* const alph_dec = dec->alph_dec_; const int width = alph_dec->width_; const int height = alph_dec->height_; WebPUnfilterFunc unfilter_func = WebPUnfilters[alph_dec->filter_]; uint8_t* const output = dec->alpha_plane_; if (alph_dec->method_ == ALPHA_NO_COMPRESSION) { const size_t offset = row * width; const size_t num_pixels = num_rows * width; assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN + offset + num_pixels); memcpy(dec->alpha_plane_ + offset, dec->alpha_data_ + ALPHA_HEADER_LEN + offset, num_pixels); } else { // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION assert(alph_dec->vp8l_dec_ != NULL); if (!VP8LDecodeAlphaImageStream(alph_dec, row + num_rows)) { return 0; } } if (unfilter_func != NULL) { unfilter_func(width, height, width, row, num_rows, output); } if (alph_dec->pre_processing_ == ALPHA_PREPROCESSED_LEVELS) { if (!DequantizeLevels(output, width, height, row, num_rows)) { return 0; } } if (row + num_rows == dec->pic_hdr_.height_) { dec->is_alpha_decoded_ = 1; } return 1; } //------------------------------------------------------------------------------ // Main entry point. const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec, int row, int num_rows) { const int width = dec->pic_hdr_.width_; const int height = dec->pic_hdr_.height_; if (row < 0 || num_rows <= 0 || row + num_rows > height) { return NULL; // sanity check. } if (row == 0) { // Initialize decoding. assert(dec->alpha_plane_ != NULL); dec->alph_dec_ = ALPHNew(); if (dec->alph_dec_ == NULL) return NULL; if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_, width, height, dec->alpha_plane_)) { ALPHDelete(dec->alph_dec_); dec->alph_dec_ = NULL; return NULL; } } if (!dec->is_alpha_decoded_) { int ok = 0; assert(dec->alph_dec_ != NULL); ok = ALPHDecode(dec, row, num_rows); if (!ok || dec->is_alpha_decoded_) { ALPHDelete(dec->alph_dec_); dec->alph_dec_ = NULL; } if (!ok) return NULL; // Error. } // Return a pointer to the current decoded row. return dec->alpha_plane_ + row * width; } libwebp-0.4.0/src/dec/Makefile.in0000644000014400001440000007566512255206714013465 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ subdir = src/dec DIST_COMMON = $(libwebpdecodeinclude_HEADERS) $(noinst_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libwebpdecode_la_LIBADD = am_libwebpdecode_la_OBJECTS = libwebpdecode_la-alpha.lo \ libwebpdecode_la-buffer.lo libwebpdecode_la-frame.lo \ libwebpdecode_la-idec.lo libwebpdecode_la-io.lo \ libwebpdecode_la-layer.lo libwebpdecode_la-quant.lo \ libwebpdecode_la-tree.lo libwebpdecode_la-vp8.lo \ libwebpdecode_la-vp8l.lo libwebpdecode_la-webp.lo libwebpdecode_la_OBJECTS = $(am_libwebpdecode_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebpdecode_la_SOURCES) DIST_SOURCES = $(libwebpdecode_la_SOURCES) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libwebpdecodeincludedir)" HEADERS = $(libwebpdecodeinclude_HEADERS) $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebpdecode.la libwebpdecode_la_SOURCES = alpha.c alphai.h buffer.c decode_vp8.h \ frame.c idec.c io.c layer.c quant.c tree.c vp8.c vp8i.h vp8l.c \ vp8li.h webp.c webpi.h libwebpdecodeinclude_HEADERS = ../webp/decode.h ../webp/types.h noinst_HEADERS = ../webp/format_constants.h libwebpdecode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) libwebpdecodeincludedir = $(includedir)/webp all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/dec/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/dec/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebpdecode.la: $(libwebpdecode_la_OBJECTS) $(libwebpdecode_la_DEPENDENCIES) $(EXTRA_libwebpdecode_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libwebpdecode_la_OBJECTS) $(libwebpdecode_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-alpha.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-frame.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-idec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-layer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-quant.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-tree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-vp8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-vp8l.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-webp.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 $@ $< libwebpdecode_la-alpha.lo: alpha.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-alpha.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-alpha.Tpo -c -o libwebpdecode_la-alpha.lo `test -f 'alpha.c' || echo '$(srcdir)/'`alpha.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-alpha.Tpo $(DEPDIR)/libwebpdecode_la-alpha.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha.c' object='libwebpdecode_la-alpha.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-alpha.lo `test -f 'alpha.c' || echo '$(srcdir)/'`alpha.c libwebpdecode_la-buffer.lo: buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-buffer.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-buffer.Tpo -c -o libwebpdecode_la-buffer.lo `test -f 'buffer.c' || echo '$(srcdir)/'`buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-buffer.Tpo $(DEPDIR)/libwebpdecode_la-buffer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer.c' object='libwebpdecode_la-buffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-buffer.lo `test -f 'buffer.c' || echo '$(srcdir)/'`buffer.c libwebpdecode_la-frame.lo: frame.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-frame.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-frame.Tpo -c -o libwebpdecode_la-frame.lo `test -f 'frame.c' || echo '$(srcdir)/'`frame.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-frame.Tpo $(DEPDIR)/libwebpdecode_la-frame.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame.c' object='libwebpdecode_la-frame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-frame.lo `test -f 'frame.c' || echo '$(srcdir)/'`frame.c libwebpdecode_la-idec.lo: idec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-idec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-idec.Tpo -c -o libwebpdecode_la-idec.lo `test -f 'idec.c' || echo '$(srcdir)/'`idec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-idec.Tpo $(DEPDIR)/libwebpdecode_la-idec.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='idec.c' object='libwebpdecode_la-idec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-idec.lo `test -f 'idec.c' || echo '$(srcdir)/'`idec.c libwebpdecode_la-io.lo: io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-io.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-io.Tpo -c -o libwebpdecode_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-io.Tpo $(DEPDIR)/libwebpdecode_la-io.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='libwebpdecode_la-io.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c libwebpdecode_la-layer.lo: layer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-layer.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-layer.Tpo -c -o libwebpdecode_la-layer.lo `test -f 'layer.c' || echo '$(srcdir)/'`layer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-layer.Tpo $(DEPDIR)/libwebpdecode_la-layer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='layer.c' object='libwebpdecode_la-layer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-layer.lo `test -f 'layer.c' || echo '$(srcdir)/'`layer.c libwebpdecode_la-quant.lo: quant.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-quant.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-quant.Tpo -c -o libwebpdecode_la-quant.lo `test -f 'quant.c' || echo '$(srcdir)/'`quant.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-quant.Tpo $(DEPDIR)/libwebpdecode_la-quant.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quant.c' object='libwebpdecode_la-quant.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-quant.lo `test -f 'quant.c' || echo '$(srcdir)/'`quant.c libwebpdecode_la-tree.lo: tree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-tree.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-tree.Tpo -c -o libwebpdecode_la-tree.lo `test -f 'tree.c' || echo '$(srcdir)/'`tree.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-tree.Tpo $(DEPDIR)/libwebpdecode_la-tree.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tree.c' object='libwebpdecode_la-tree.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-tree.lo `test -f 'tree.c' || echo '$(srcdir)/'`tree.c libwebpdecode_la-vp8.lo: vp8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-vp8.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-vp8.Tpo -c -o libwebpdecode_la-vp8.lo `test -f 'vp8.c' || echo '$(srcdir)/'`vp8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-vp8.Tpo $(DEPDIR)/libwebpdecode_la-vp8.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vp8.c' object='libwebpdecode_la-vp8.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-vp8.lo `test -f 'vp8.c' || echo '$(srcdir)/'`vp8.c libwebpdecode_la-vp8l.lo: vp8l.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-vp8l.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-vp8l.Tpo -c -o libwebpdecode_la-vp8l.lo `test -f 'vp8l.c' || echo '$(srcdir)/'`vp8l.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-vp8l.Tpo $(DEPDIR)/libwebpdecode_la-vp8l.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vp8l.c' object='libwebpdecode_la-vp8l.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-vp8l.lo `test -f 'vp8l.c' || echo '$(srcdir)/'`vp8l.c libwebpdecode_la-webp.lo: webp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-webp.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-webp.Tpo -c -o libwebpdecode_la-webp.lo `test -f 'webp.c' || echo '$(srcdir)/'`webp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-webp.Tpo $(DEPDIR)/libwebpdecode_la-webp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='webp.c' object='libwebpdecode_la-webp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-webp.lo `test -f 'webp.c' || echo '$(srcdir)/'`webp.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-libwebpdecodeincludeHEADERS: $(libwebpdecodeinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(libwebpdecodeincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libwebpdecodeincludedir)" @list='$(libwebpdecodeinclude_HEADERS)'; test -n "$(libwebpdecodeincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpdecodeincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpdecodeincludedir)" || exit $$?; \ done uninstall-libwebpdecodeincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libwebpdecodeinclude_HEADERS)'; test -n "$(libwebpdecodeincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libwebpdecodeincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libwebpdecodeincludedir)"; 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-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-libwebpdecodeincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: 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 -rf ./$(DEPDIR) -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-libwebpdecodeincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags 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-libwebpdecodeincludeHEADERS 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 uninstall uninstall-am \ uninstall-libwebpdecodeincludeHEADERS # 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: libwebp-0.4.0/src/dec/io.c0000644000014400001440000005265012255002107012146 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // functions for sample output. // // Author: Skal (pascal.massimino@gmail.com) #include #include #include "../dec/vp8i.h" #include "./webpi.h" #include "../dsp/dsp.h" #include "../dsp/yuv.h" //------------------------------------------------------------------------------ // Main YUV<->RGB conversion functions static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) { WebPDecBuffer* output = p->output; const WebPYUVABuffer* const buf = &output->u.YUVA; uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride; uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride; uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride; const int mb_w = io->mb_w; const int mb_h = io->mb_h; const int uv_w = (mb_w + 1) / 2; const int uv_h = (mb_h + 1) / 2; int j; for (j = 0; j < mb_h; ++j) { memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w); } for (j = 0; j < uv_h; ++j) { memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w); memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w); } return io->mb_h; } // Point-sampling U/V sampler. static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) { WebPDecBuffer* output = p->output; const WebPRGBABuffer* const buf = &output->u.RGBA; uint8_t* dst = buf->rgba + io->mb_y * buf->stride; const uint8_t* y_src = io->y; const uint8_t* u_src = io->u; const uint8_t* v_src = io->v; const WebPSampleLinePairFunc sample = WebPSamplers[output->colorspace]; const int mb_w = io->mb_w; const int last = io->mb_h - 1; int j; for (j = 0; j < last; j += 2) { sample(y_src, y_src + io->y_stride, u_src, v_src, dst, dst + buf->stride, mb_w); y_src += 2 * io->y_stride; u_src += io->uv_stride; v_src += io->uv_stride; dst += 2 * buf->stride; } if (j == last) { // Just do the last line twice sample(y_src, y_src, u_src, v_src, dst, dst, mb_w); } return io->mb_h; } //------------------------------------------------------------------------------ // YUV444 -> RGB conversion #if 0 // TODO(skal): this is for future rescaling. static int EmitRGB(const VP8Io* const io, WebPDecParams* const p) { WebPDecBuffer* output = p->output; const WebPRGBABuffer* const buf = &output->u.RGBA; uint8_t* dst = buf->rgba + io->mb_y * buf->stride; const uint8_t* y_src = io->y; const uint8_t* u_src = io->u; const uint8_t* v_src = io->v; const WebPYUV444Converter convert = WebPYUV444Converters[output->colorspace]; const int mb_w = io->mb_w; const int last = io->mb_h; int j; for (j = 0; j < last; ++j) { convert(y_src, u_src, v_src, dst, mb_w); y_src += io->y_stride; u_src += io->uv_stride; v_src += io->uv_stride; dst += buf->stride; } return io->mb_h; } #endif //------------------------------------------------------------------------------ // Fancy upsampling #ifdef FANCY_UPSAMPLING static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) { int num_lines_out = io->mb_h; // a priori guess const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* dst = buf->rgba + io->mb_y * buf->stride; WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace]; const uint8_t* cur_y = io->y; const uint8_t* cur_u = io->u; const uint8_t* cur_v = io->v; const uint8_t* top_u = p->tmp_u; const uint8_t* top_v = p->tmp_v; int y = io->mb_y; const int y_end = io->mb_y + io->mb_h; const int mb_w = io->mb_w; const int uv_w = (mb_w + 1) / 2; if (y == 0) { // First line is special cased. We mirror the u/v samples at boundary. upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, mb_w); } else { // We can finish the left-over line from previous call. upsample(p->tmp_y, cur_y, top_u, top_v, cur_u, cur_v, dst - buf->stride, dst, mb_w); ++num_lines_out; } // Loop over each output pairs of row. for (; y + 2 < y_end; y += 2) { top_u = cur_u; top_v = cur_v; cur_u += io->uv_stride; cur_v += io->uv_stride; dst += 2 * buf->stride; cur_y += 2 * io->y_stride; upsample(cur_y - io->y_stride, cur_y, top_u, top_v, cur_u, cur_v, dst - buf->stride, dst, mb_w); } // move to last row cur_y += io->y_stride; if (io->crop_top + y_end < io->crop_bottom) { // Save the unfinished samples for next call (as we're not done yet). memcpy(p->tmp_y, cur_y, mb_w * sizeof(*p->tmp_y)); memcpy(p->tmp_u, cur_u, uv_w * sizeof(*p->tmp_u)); memcpy(p->tmp_v, cur_v, uv_w * sizeof(*p->tmp_v)); // The fancy upsampler leaves a row unfinished behind // (except for the very last row) num_lines_out--; } else { // Process the very last row of even-sized picture if (!(y_end & 1)) { upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst + buf->stride, NULL, mb_w); } } return num_lines_out; } #endif /* FANCY_UPSAMPLING */ //------------------------------------------------------------------------------ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p) { const uint8_t* alpha = io->a; const WebPYUVABuffer* const buf = &p->output->u.YUVA; const int mb_w = io->mb_w; const int mb_h = io->mb_h; uint8_t* dst = buf->a + io->mb_y * buf->a_stride; int j; if (alpha != NULL) { for (j = 0; j < mb_h; ++j) { memcpy(dst, alpha, mb_w * sizeof(*dst)); alpha += io->width; dst += buf->a_stride; } } else if (buf->a != NULL) { // the user requested alpha, but there is none, set it to opaque. for (j = 0; j < mb_h; ++j) { memset(dst, 0xff, mb_w * sizeof(*dst)); dst += buf->a_stride; } } return 0; } static int GetAlphaSourceRow(const VP8Io* const io, const uint8_t** alpha, int* const num_rows) { int start_y = io->mb_y; *num_rows = io->mb_h; // Compensate for the 1-line delay of the fancy upscaler. // This is similar to EmitFancyRGB(). if (io->fancy_upsampling) { if (start_y == 0) { // We don't process the last row yet. It'll be done during the next call. --*num_rows; } else { --start_y; // Fortunately, *alpha data is persistent, so we can go back // one row and finish alpha blending, now that the fancy upscaler // completed the YUV->RGB interpolation. *alpha -= io->width; } if (io->crop_top + io->mb_y + io->mb_h == io->crop_bottom) { // If it's the very last call, we process all the remaining rows! *num_rows = io->crop_bottom - io->crop_top - start_y; } } return start_y; } static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p) { const uint8_t* alpha = io->a; if (alpha != NULL) { const int mb_w = io->mb_w; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int alpha_first = (colorspace == MODE_ARGB || colorspace == MODE_Argb); const WebPRGBABuffer* const buf = &p->output->u.RGBA; int num_rows; const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows); uint8_t* const base_rgba = buf->rgba + start_y * buf->stride; uint8_t* dst = base_rgba + (alpha_first ? 0 : 3); uint32_t alpha_mask = 0xff; int i, j; for (j = 0; j < num_rows; ++j) { for (i = 0; i < mb_w; ++i) { const uint32_t alpha_value = alpha[i]; dst[4 * i] = alpha_value; alpha_mask &= alpha_value; } alpha += io->width; dst += buf->stride; } // alpha_mask is < 0xff if there's non-trivial alpha to premultiply with. if (alpha_mask != 0xff && WebPIsPremultipliedMode(colorspace)) { WebPApplyAlphaMultiply(base_rgba, alpha_first, mb_w, num_rows, buf->stride); } } return 0; } static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p) { const uint8_t* alpha = io->a; if (alpha != NULL) { const int mb_w = io->mb_w; const WEBP_CSP_MODE colorspace = p->output->colorspace; const WebPRGBABuffer* const buf = &p->output->u.RGBA; int num_rows; const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows); uint8_t* const base_rgba = buf->rgba + start_y * buf->stride; uint8_t* alpha_dst = base_rgba + 1; uint32_t alpha_mask = 0x0f; int i, j; for (j = 0; j < num_rows; ++j) { for (i = 0; i < mb_w; ++i) { // Fill in the alpha value (converted to 4 bits). const uint32_t alpha_value = alpha[i] >> 4; alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value; alpha_mask &= alpha_value; } alpha += io->width; alpha_dst += buf->stride; } if (alpha_mask != 0x0f && WebPIsPremultipliedMode(colorspace)) { WebPApplyAlphaMultiply4444(base_rgba, mb_w, num_rows, buf->stride); } } return 0; } //------------------------------------------------------------------------------ // YUV rescaling (no final RGB conversion needed) static int Rescale(const uint8_t* src, int src_stride, int new_lines, WebPRescaler* const wrk) { int num_lines_out = 0; while (new_lines > 0) { // import new contributions of source rows. const int lines_in = WebPRescalerImport(wrk, new_lines, src, src_stride); src += lines_in * src_stride; new_lines -= lines_in; num_lines_out += WebPRescalerExport(wrk); // emit output row(s) } return num_lines_out; } static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) { const int mb_h = io->mb_h; const int uv_mb_h = (mb_h + 1) >> 1; const int num_lines_out = Rescale(io->y, io->y_stride, mb_h, &p->scaler_y); Rescale(io->u, io->uv_stride, uv_mb_h, &p->scaler_u); Rescale(io->v, io->uv_stride, uv_mb_h, &p->scaler_v); return num_lines_out; } static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p) { if (io->a != NULL) { Rescale(io->a, io->width, io->mb_h, &p->scaler_a); } return 0; } static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) { const int has_alpha = WebPIsAlphaMode(p->output->colorspace); const WebPYUVABuffer* const buf = &p->output->u.YUVA; const int out_width = io->scaled_width; const int out_height = io->scaled_height; const int uv_out_width = (out_width + 1) >> 1; const int uv_out_height = (out_height + 1) >> 1; const int uv_in_width = (io->mb_w + 1) >> 1; const int uv_in_height = (io->mb_h + 1) >> 1; const size_t work_size = 2 * out_width; // scratch memory for luma rescaler const size_t uv_work_size = 2 * uv_out_width; // and for each u/v ones size_t tmp_size; int32_t* work; tmp_size = work_size + 2 * uv_work_size; if (has_alpha) { tmp_size += work_size; } p->memory = calloc(1, tmp_size * sizeof(*work)); if (p->memory == NULL) { return 0; // memory error } work = (int32_t*)p->memory; WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h, buf->y, out_width, out_height, buf->y_stride, 1, io->mb_w, out_width, io->mb_h, out_height, work); WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height, buf->u, uv_out_width, uv_out_height, buf->u_stride, 1, uv_in_width, uv_out_width, uv_in_height, uv_out_height, work + work_size); WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height, buf->v, uv_out_width, uv_out_height, buf->v_stride, 1, uv_in_width, uv_out_width, uv_in_height, uv_out_height, work + work_size + uv_work_size); p->emit = EmitRescaledYUV; if (has_alpha) { WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h, buf->a, out_width, out_height, buf->a_stride, 1, io->mb_w, out_width, io->mb_h, out_height, work + work_size + 2 * uv_work_size); p->emit_alpha = EmitRescaledAlphaYUV; } return 1; } //------------------------------------------------------------------------------ // RGBA rescaling static int ExportRGB(WebPDecParams* const p, int y_pos) { const WebPYUV444Converter convert = WebPYUV444Converters[p->output->colorspace]; const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* dst = buf->rgba + (p->last_y + y_pos) * buf->stride; int num_lines_out = 0; // For RGB rescaling, because of the YUV420, current scan position // U/V can be +1/-1 line from the Y one. Hence the double test. while (WebPRescalerHasPendingOutput(&p->scaler_y) && WebPRescalerHasPendingOutput(&p->scaler_u)) { assert(p->last_y + y_pos + num_lines_out < p->output->height); assert(p->scaler_u.y_accum == p->scaler_v.y_accum); WebPRescalerExportRow(&p->scaler_y); WebPRescalerExportRow(&p->scaler_u); WebPRescalerExportRow(&p->scaler_v); convert(p->scaler_y.dst, p->scaler_u.dst, p->scaler_v.dst, dst, p->scaler_y.dst_width); dst += buf->stride; ++num_lines_out; } return num_lines_out; } static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) { const int mb_h = io->mb_h; const int uv_mb_h = (mb_h + 1) >> 1; int j = 0, uv_j = 0; int num_lines_out = 0; while (j < mb_h) { const int y_lines_in = WebPRescalerImport(&p->scaler_y, mb_h - j, io->y + j * io->y_stride, io->y_stride); const int u_lines_in = WebPRescalerImport(&p->scaler_u, uv_mb_h - uv_j, io->u + uv_j * io->uv_stride, io->uv_stride); const int v_lines_in = WebPRescalerImport(&p->scaler_v, uv_mb_h - uv_j, io->v + uv_j * io->uv_stride, io->uv_stride); (void)v_lines_in; // remove a gcc warning assert(u_lines_in == v_lines_in); j += y_lines_in; uv_j += u_lines_in; num_lines_out += ExportRGB(p, num_lines_out); } return num_lines_out; } static int ExportAlpha(WebPDecParams* const p, int y_pos) { const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int alpha_first = (colorspace == MODE_ARGB || colorspace == MODE_Argb); uint8_t* dst = base_rgba + (alpha_first ? 0 : 3); int num_lines_out = 0; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t alpha_mask = 0xff; const int width = p->scaler_a.dst_width; while (WebPRescalerHasPendingOutput(&p->scaler_a)) { int i; assert(p->last_y + y_pos + num_lines_out < p->output->height); WebPRescalerExportRow(&p->scaler_a); for (i = 0; i < width; ++i) { const uint32_t alpha_value = p->scaler_a.dst[i]; dst[4 * i] = alpha_value; alpha_mask &= alpha_value; } dst += buf->stride; ++num_lines_out; } if (is_premult_alpha && alpha_mask != 0xff) { WebPApplyAlphaMultiply(base_rgba, alpha_first, width, num_lines_out, buf->stride); } return num_lines_out; } static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos) { const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride; uint8_t* alpha_dst = base_rgba + 1; int num_lines_out = 0; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int width = p->scaler_a.dst_width; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t alpha_mask = 0x0f; while (WebPRescalerHasPendingOutput(&p->scaler_a)) { int i; assert(p->last_y + y_pos + num_lines_out < p->output->height); WebPRescalerExportRow(&p->scaler_a); for (i = 0; i < width; ++i) { // Fill in the alpha value (converted to 4 bits). const uint32_t alpha_value = p->scaler_a.dst[i] >> 4; alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value; alpha_mask &= alpha_value; } alpha_dst += buf->stride; ++num_lines_out; } if (is_premult_alpha && alpha_mask != 0x0f) { WebPApplyAlphaMultiply4444(base_rgba, width, num_lines_out, buf->stride); } return num_lines_out; } static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p) { if (io->a != NULL) { WebPRescaler* const scaler = &p->scaler_a; int j = 0; int pos = 0; while (j < io->mb_h) { j += WebPRescalerImport(scaler, io->mb_h - j, io->a + j * io->width, io->width); pos += p->emit_alpha_row(p, pos); } } return 0; } static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) { const int has_alpha = WebPIsAlphaMode(p->output->colorspace); const int out_width = io->scaled_width; const int out_height = io->scaled_height; const int uv_in_width = (io->mb_w + 1) >> 1; const int uv_in_height = (io->mb_h + 1) >> 1; const size_t work_size = 2 * out_width; // scratch memory for one rescaler int32_t* work; // rescalers work area uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion size_t tmp_size1, tmp_size2; tmp_size1 = 3 * work_size; tmp_size2 = 3 * out_width; if (has_alpha) { tmp_size1 += work_size; tmp_size2 += out_width; } p->memory = calloc(1, tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp)); if (p->memory == NULL) { return 0; // memory error } work = (int32_t*)p->memory; tmp = (uint8_t*)(work + tmp_size1); WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h, tmp + 0 * out_width, out_width, out_height, 0, 1, io->mb_w, out_width, io->mb_h, out_height, work + 0 * work_size); WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height, tmp + 1 * out_width, out_width, out_height, 0, 1, io->mb_w, 2 * out_width, io->mb_h, 2 * out_height, work + 1 * work_size); WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height, tmp + 2 * out_width, out_width, out_height, 0, 1, io->mb_w, 2 * out_width, io->mb_h, 2 * out_height, work + 2 * work_size); p->emit = EmitRescaledRGB; if (has_alpha) { WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h, tmp + 3 * out_width, out_width, out_height, 0, 1, io->mb_w, out_width, io->mb_h, out_height, work + 3 * work_size); p->emit_alpha = EmitRescaledAlphaRGB; if (p->output->colorspace == MODE_RGBA_4444 || p->output->colorspace == MODE_rgbA_4444) { p->emit_alpha_row = ExportAlphaRGBA4444; } else { p->emit_alpha_row = ExportAlpha; } } return 1; } //------------------------------------------------------------------------------ // Default custom functions static int CustomSetup(VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int is_rgb = WebPIsRGBMode(colorspace); const int is_alpha = WebPIsAlphaMode(colorspace); p->memory = NULL; p->emit = NULL; p->emit_alpha = NULL; p->emit_alpha_row = NULL; if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) { return 0; } if (io->use_scaling) { const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p); if (!ok) { return 0; // memory error } } else { if (is_rgb) { p->emit = EmitSampledRGB; // default #ifdef FANCY_UPSAMPLING if (io->fancy_upsampling) { const int uv_width = (io->mb_w + 1) >> 1; p->memory = malloc(io->mb_w + 2 * uv_width); if (p->memory == NULL) { return 0; // memory error. } p->tmp_y = (uint8_t*)p->memory; p->tmp_u = p->tmp_y + io->mb_w; p->tmp_v = p->tmp_u + uv_width; p->emit = EmitFancyRGB; WebPInitUpsamplers(); } #endif } else { p->emit = EmitYUV; } if (is_alpha) { // need transparency output if (WebPIsPremultipliedMode(colorspace)) WebPInitPremultiply(); p->emit_alpha = (colorspace == MODE_RGBA_4444 || colorspace == MODE_rgbA_4444) ? EmitAlphaRGBA4444 : is_rgb ? EmitAlphaRGB : EmitAlphaYUV; } } if (is_rgb) { VP8YUVInit(); } return 1; } //------------------------------------------------------------------------------ static int CustomPut(const VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; const int mb_w = io->mb_w; const int mb_h = io->mb_h; int num_lines_out; assert(!(io->mb_y & 1)); if (mb_w <= 0 || mb_h <= 0) { return 0; } num_lines_out = p->emit(io, p); if (p->emit_alpha != NULL) { p->emit_alpha(io, p); } p->last_y += num_lines_out; return 1; } //------------------------------------------------------------------------------ static void CustomTeardown(const VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; free(p->memory); p->memory = NULL; } //------------------------------------------------------------------------------ // Main entry point void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io) { io->put = CustomPut; io->setup = CustomSetup; io->teardown = CustomTeardown; io->opaque = params; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/webpi.h0000644000014400001440000001206412255002107012645 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Internal header: WebP decoding parameters and custom IO on buffer // // Author: somnath@google.com (Somnath Banerjee) #ifndef WEBP_DEC_WEBPI_H_ #define WEBP_DEC_WEBPI_H_ #ifdef __cplusplus extern "C" { #endif #include "../utils/rescaler.h" #include "./decode_vp8.h" //------------------------------------------------------------------------------ // WebPDecParams: Decoding output parameters. Transient internal object. typedef struct WebPDecParams WebPDecParams; typedef int (*OutputFunc)(const VP8Io* const io, WebPDecParams* const p); typedef int (*OutputRowFunc)(WebPDecParams* const p, int y_pos); struct WebPDecParams { WebPDecBuffer* output; // output buffer. uint8_t* tmp_y, *tmp_u, *tmp_v; // cache for the fancy upsampler // or used for tmp rescaling int last_y; // coordinate of the line that was last output const WebPDecoderOptions* options; // if not NULL, use alt decoding features // rescalers WebPRescaler scaler_y, scaler_u, scaler_v, scaler_a; void* memory; // overall scratch memory for the output work. OutputFunc emit; // output RGB or YUV samples OutputFunc emit_alpha; // output alpha channel OutputRowFunc emit_alpha_row; // output one line of rescaled alpha values }; // Should be called first, before any use of the WebPDecParams object. void WebPResetDecParams(WebPDecParams* const params); //------------------------------------------------------------------------------ // Header parsing helpers // Structure storing a description of the RIFF headers. typedef struct { const uint8_t* data; // input buffer size_t data_size; // input buffer size size_t offset; // offset to main data chunk (VP8 or VP8L) const uint8_t* alpha_data; // points to alpha chunk (if present) size_t alpha_data_size; // alpha chunk size size_t compressed_size; // VP8/VP8L compressed data size size_t riff_size; // size of the riff payload (or 0 if absent) int is_lossless; // true if a VP8L chunk is present } WebPHeaderStructure; // Skips over all valid chunks prior to the first VP8/VP8L frame header. // Returns: VP8_STATUS_OK, VP8_STATUS_BITSTREAM_ERROR (invalid header/chunk), // VP8_STATUS_NOT_ENOUGH_DATA (partial input) or VP8_STATUS_UNSUPPORTED_FEATURE // in the case of non-decodable features (animation for instance). // In 'headers', compressed_size, offset, alpha_data, alpha_size, and lossless // fields are updated appropriately upon success. VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers); //------------------------------------------------------------------------------ // Misc utils // Initializes VP8Io with custom setup, io and teardown functions. The default // hooks will use the supplied 'params' as io->opaque handle. void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io); // Setup crop_xxx fields, mb_w and mb_h in io. 'src_colorspace' refers // to the *compressed* format, not the output one. int WebPIoInitFromOptions(const WebPDecoderOptions* const options, VP8Io* const io, WEBP_CSP_MODE src_colorspace); //------------------------------------------------------------------------------ // Internal functions regarding WebPDecBuffer memory (in buffer.c). // Don't really need to be externally visible for now. // Prepare 'buffer' with the requested initial dimensions width/height. // If no external storage is supplied, initializes buffer by allocating output // memory and setting up the stride information. Validate the parameters. Return // an error code in case of problem (no memory, or invalid stride / size / // dimension / etc.). If *options is not NULL, also verify that the options' // parameters are valid and apply them to the width/height dimensions of the // output buffer. This takes cropping / scaling / rotation into account. VP8StatusCode WebPAllocateDecBuffer(int width, int height, const WebPDecoderOptions* const options, WebPDecBuffer* const buffer); // Copy 'src' into 'dst' buffer, making sure 'dst' is not marked as owner of the // memory (still held by 'src'). void WebPCopyDecBuffer(const WebPDecBuffer* const src, WebPDecBuffer* const dst); // Copy and transfer ownership from src to dst (beware of parameter order!) void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_DEC_WEBPI_H_ */ libwebp-0.4.0/src/dec/webp.c0000644000014400001440000007027112255002107012473 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Main decoding functions for WEBP images. // // Author: Skal (pascal.massimino@gmail.com) #include #include "./vp8i.h" #include "./vp8li.h" #include "./webpi.h" #include "../webp/mux_types.h" // ALPHA_FLAG //------------------------------------------------------------------------------ // RIFF layout is: // Offset tag // 0...3 "RIFF" 4-byte tag // 4...7 size of image data (including metadata) starting at offset 8 // 8...11 "WEBP" our form-type signature // The RIFF container (12 bytes) is followed by appropriate chunks: // 12..15 "VP8 ": 4-bytes tags, signaling the use of VP8 video format // 16..19 size of the raw VP8 image data, starting at offset 20 // 20.... the VP8 bytes // Or, // 12..15 "VP8L": 4-bytes tags, signaling the use of VP8L lossless format // 16..19 size of the raw VP8L image data, starting at offset 20 // 20.... the VP8L bytes // Or, // 12..15 "VP8X": 4-bytes tags, describing the extended-VP8 chunk. // 16..19 size of the VP8X chunk starting at offset 20. // 20..23 VP8X flags bit-map corresponding to the chunk-types present. // 24..26 Width of the Canvas Image. // 27..29 Height of the Canvas Image. // There can be extra chunks after the "VP8X" chunk (ICCP, FRGM, ANMF, VP8, // VP8L, XMP, EXIF ...) // All sizes are in little-endian order. // Note: chunk data size must be padded to multiple of 2 when written. static WEBP_INLINE uint32_t get_le24(const uint8_t* const data) { return data[0] | (data[1] << 8) | (data[2] << 16); } static WEBP_INLINE uint32_t get_le32(const uint8_t* const data) { return (uint32_t)get_le24(data) | (data[3] << 24); } // Validates the RIFF container (if detected) and skips over it. // If a RIFF container is detected, // Returns VP8_STATUS_BITSTREAM_ERROR for invalid header, and // VP8_STATUS_OK otherwise. // In case there are not enough bytes (partial RIFF container), return 0 for // *riff_size. Else return the RIFF size extracted from the header. static VP8StatusCode ParseRIFF(const uint8_t** const data, size_t* const data_size, size_t* const riff_size) { assert(data != NULL); assert(data_size != NULL); assert(riff_size != NULL); *riff_size = 0; // Default: no RIFF present. if (*data_size >= RIFF_HEADER_SIZE && !memcmp(*data, "RIFF", TAG_SIZE)) { if (memcmp(*data + 8, "WEBP", TAG_SIZE)) { return VP8_STATUS_BITSTREAM_ERROR; // Wrong image file signature. } else { const uint32_t size = get_le32(*data + TAG_SIZE); // Check that we have at least one chunk (i.e "WEBP" + "VP8?nnnn"). if (size < TAG_SIZE + CHUNK_HEADER_SIZE) { return VP8_STATUS_BITSTREAM_ERROR; } if (size > MAX_CHUNK_PAYLOAD) { return VP8_STATUS_BITSTREAM_ERROR; } // We have a RIFF container. Skip it. *riff_size = size; *data += RIFF_HEADER_SIZE; *data_size -= RIFF_HEADER_SIZE; } } return VP8_STATUS_OK; } // Validates the VP8X header and skips over it. // Returns VP8_STATUS_BITSTREAM_ERROR for invalid VP8X header, // VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and // VP8_STATUS_OK otherwise. // If a VP8X chunk is found, found_vp8x is set to true and *width_ptr, // *height_ptr and *flags_ptr are set to the corresponding values extracted // from the VP8X chunk. static VP8StatusCode ParseVP8X(const uint8_t** const data, size_t* const data_size, int* const found_vp8x, int* const width_ptr, int* const height_ptr, uint32_t* const flags_ptr) { const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE; assert(data != NULL); assert(data_size != NULL); assert(found_vp8x != NULL); *found_vp8x = 0; if (*data_size < CHUNK_HEADER_SIZE) { return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. } if (!memcmp(*data, "VP8X", TAG_SIZE)) { int width, height; uint32_t flags; const uint32_t chunk_size = get_le32(*data + TAG_SIZE); if (chunk_size != VP8X_CHUNK_SIZE) { return VP8_STATUS_BITSTREAM_ERROR; // Wrong chunk size. } // Verify if enough data is available to validate the VP8X chunk. if (*data_size < vp8x_size) { return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. } flags = get_le32(*data + 8); width = 1 + get_le24(*data + 12); height = 1 + get_le24(*data + 15); if (width * (uint64_t)height >= MAX_IMAGE_AREA) { return VP8_STATUS_BITSTREAM_ERROR; // image is too large } if (flags_ptr != NULL) *flags_ptr = flags; if (width_ptr != NULL) *width_ptr = width; if (height_ptr != NULL) *height_ptr = height; // Skip over VP8X header bytes. *data += vp8x_size; *data_size -= vp8x_size; *found_vp8x = 1; } return VP8_STATUS_OK; } // Skips to the next VP8/VP8L chunk header in the data given the size of the // RIFF chunk 'riff_size'. // Returns VP8_STATUS_BITSTREAM_ERROR if any invalid chunk size is encountered, // VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and // VP8_STATUS_OK otherwise. // If an alpha chunk is found, *alpha_data and *alpha_size are set // appropriately. static VP8StatusCode ParseOptionalChunks(const uint8_t** const data, size_t* const data_size, size_t const riff_size, const uint8_t** const alpha_data, size_t* const alpha_size) { const uint8_t* buf; size_t buf_size; uint32_t total_size = TAG_SIZE + // "WEBP". CHUNK_HEADER_SIZE + // "VP8Xnnnn". VP8X_CHUNK_SIZE; // data. assert(data != NULL); assert(data_size != NULL); buf = *data; buf_size = *data_size; assert(alpha_data != NULL); assert(alpha_size != NULL); *alpha_data = NULL; *alpha_size = 0; while (1) { uint32_t chunk_size; uint32_t disk_chunk_size; // chunk_size with padding *data = buf; *data_size = buf_size; if (buf_size < CHUNK_HEADER_SIZE) { // Insufficient data. return VP8_STATUS_NOT_ENOUGH_DATA; } chunk_size = get_le32(buf + TAG_SIZE); if (chunk_size > MAX_CHUNK_PAYLOAD) { return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size. } // For odd-sized chunk-payload, there's one byte padding at the end. disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1; total_size += disk_chunk_size; // Check that total bytes skipped so far does not exceed riff_size. if (riff_size > 0 && (total_size > riff_size)) { return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size. } // Start of a (possibly incomplete) VP8/VP8L chunk implies that we have // parsed all the optional chunks. // Note: This check must occur before the check 'buf_size < disk_chunk_size' // below to allow incomplete VP8/VP8L chunks. if (!memcmp(buf, "VP8 ", TAG_SIZE) || !memcmp(buf, "VP8L", TAG_SIZE)) { return VP8_STATUS_OK; } if (buf_size < disk_chunk_size) { // Insufficient data. return VP8_STATUS_NOT_ENOUGH_DATA; } if (!memcmp(buf, "ALPH", TAG_SIZE)) { // A valid ALPH header. *alpha_data = buf + CHUNK_HEADER_SIZE; *alpha_size = chunk_size; } // We have a full and valid chunk; skip it. buf += disk_chunk_size; buf_size -= disk_chunk_size; } } // Validates the VP8/VP8L Header ("VP8 nnnn" or "VP8L nnnn") and skips over it. // Returns VP8_STATUS_BITSTREAM_ERROR for invalid (chunk larger than // riff_size) VP8/VP8L header, // VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and // VP8_STATUS_OK otherwise. // If a VP8/VP8L chunk is found, *chunk_size is set to the total number of bytes // extracted from the VP8/VP8L chunk header. // The flag '*is_lossless' is set to 1 in case of VP8L chunk / raw VP8L data. static VP8StatusCode ParseVP8Header(const uint8_t** const data_ptr, size_t* const data_size, size_t riff_size, size_t* const chunk_size, int* const is_lossless) { const uint8_t* const data = *data_ptr; const int is_vp8 = !memcmp(data, "VP8 ", TAG_SIZE); const int is_vp8l = !memcmp(data, "VP8L", TAG_SIZE); const uint32_t minimal_size = TAG_SIZE + CHUNK_HEADER_SIZE; // "WEBP" + "VP8 nnnn" OR // "WEBP" + "VP8Lnnnn" assert(data != NULL); assert(data_size != NULL); assert(chunk_size != NULL); assert(is_lossless != NULL); if (*data_size < CHUNK_HEADER_SIZE) { return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. } if (is_vp8 || is_vp8l) { // Bitstream contains VP8/VP8L header. const uint32_t size = get_le32(data + TAG_SIZE); if ((riff_size >= minimal_size) && (size > riff_size - minimal_size)) { return VP8_STATUS_BITSTREAM_ERROR; // Inconsistent size information. } // Skip over CHUNK_HEADER_SIZE bytes from VP8/VP8L Header. *chunk_size = size; *data_ptr += CHUNK_HEADER_SIZE; *data_size -= CHUNK_HEADER_SIZE; *is_lossless = is_vp8l; } else { // Raw VP8/VP8L bitstream (no header). *is_lossless = VP8LCheckSignature(data, *data_size); *chunk_size = *data_size; } return VP8_STATUS_OK; } //------------------------------------------------------------------------------ // Fetch '*width', '*height', '*has_alpha' and fill out 'headers' based on // 'data'. All the output parameters may be NULL. If 'headers' is NULL only the // minimal amount will be read to fetch the remaining parameters. // If 'headers' is non-NULL this function will attempt to locate both alpha // data (with or without a VP8X chunk) and the bitstream chunk (VP8/VP8L). // Note: The following chunk sequences (before the raw VP8/VP8L data) are // considered valid by this function: // RIFF + VP8(L) // RIFF + VP8X + (optional chunks) + VP8(L) // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. static VP8StatusCode ParseHeadersInternal(const uint8_t* data, size_t data_size, int* const width, int* const height, int* const has_alpha, int* const has_animation, int* const format, WebPHeaderStructure* const headers) { int canvas_width = 0; int canvas_height = 0; int image_width = 0; int image_height = 0; int found_riff = 0; int found_vp8x = 0; int animation_present = 0; int fragments_present = 0; VP8StatusCode status; WebPHeaderStructure hdrs; if (data == NULL || data_size < RIFF_HEADER_SIZE) { return VP8_STATUS_NOT_ENOUGH_DATA; } memset(&hdrs, 0, sizeof(hdrs)); hdrs.data = data; hdrs.data_size = data_size; // Skip over RIFF header. status = ParseRIFF(&data, &data_size, &hdrs.riff_size); if (status != VP8_STATUS_OK) { return status; // Wrong RIFF header / insufficient data. } found_riff = (hdrs.riff_size > 0); // Skip over VP8X. { uint32_t flags = 0; status = ParseVP8X(&data, &data_size, &found_vp8x, &canvas_width, &canvas_height, &flags); if (status != VP8_STATUS_OK) { return status; // Wrong VP8X / insufficient data. } animation_present = !!(flags & ANIMATION_FLAG); fragments_present = !!(flags & FRAGMENTS_FLAG); if (!found_riff && found_vp8x) { // Note: This restriction may be removed in the future, if it becomes // necessary to send VP8X chunk to the decoder. return VP8_STATUS_BITSTREAM_ERROR; } if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG); if (has_animation != NULL) *has_animation = animation_present; if (format != NULL) *format = 0; // default = undefined image_width = canvas_width; image_height = canvas_height; if (found_vp8x && (animation_present || fragments_present) && headers == NULL) { status = VP8_STATUS_OK; goto ReturnWidthHeight; // Just return features from VP8X header. } } if (data_size < TAG_SIZE) { status = VP8_STATUS_NOT_ENOUGH_DATA; goto ReturnWidthHeight; } // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH". if ((found_riff && found_vp8x) || (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) { status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size, &hdrs.alpha_data, &hdrs.alpha_data_size); if (status != VP8_STATUS_OK) { goto ReturnWidthHeight; // Invalid chunk size / insufficient data. } } // Skip over VP8/VP8L header. status = ParseVP8Header(&data, &data_size, hdrs.riff_size, &hdrs.compressed_size, &hdrs.is_lossless); if (status != VP8_STATUS_OK) { goto ReturnWidthHeight; // Wrong VP8/VP8L chunk-header / insufficient data. } if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) { return VP8_STATUS_BITSTREAM_ERROR; } if (format != NULL && !(animation_present || fragments_present)) { *format = hdrs.is_lossless ? 2 : 1; } if (!hdrs.is_lossless) { if (data_size < VP8_FRAME_HEADER_SIZE) { status = VP8_STATUS_NOT_ENOUGH_DATA; goto ReturnWidthHeight; } // Validates raw VP8 data. if (!VP8GetInfo(data, data_size, (uint32_t)hdrs.compressed_size, &image_width, &image_height)) { return VP8_STATUS_BITSTREAM_ERROR; } } else { if (data_size < VP8L_FRAME_HEADER_SIZE) { status = VP8_STATUS_NOT_ENOUGH_DATA; goto ReturnWidthHeight; } // Validates raw VP8L data. if (!VP8LGetInfo(data, data_size, &image_width, &image_height, has_alpha)) { return VP8_STATUS_BITSTREAM_ERROR; } } // Validates image size coherency. if (found_vp8x) { if (canvas_width != image_width || canvas_height != image_height) { return VP8_STATUS_BITSTREAM_ERROR; } } if (headers != NULL) { *headers = hdrs; headers->offset = data - headers->data; assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD); assert(headers->offset == headers->data_size - data_size); } ReturnWidthHeight: if (status == VP8_STATUS_OK || (status == VP8_STATUS_NOT_ENOUGH_DATA && found_vp8x && headers == NULL)) { if (has_alpha != NULL) { // If the data did not contain a VP8X/VP8L chunk the only definitive way // to set this is by looking for alpha data (from an ALPH chunk). *has_alpha |= (hdrs.alpha_data != NULL); } if (width != NULL) *width = image_width; if (height != NULL) *height = image_height; return VP8_STATUS_OK; } else { return status; } } VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { VP8StatusCode status; int has_animation = 0; assert(headers != NULL); // fill out headers, ignore width/height/has_alpha. status = ParseHeadersInternal(headers->data, headers->data_size, NULL, NULL, NULL, &has_animation, NULL, headers); if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) { // TODO(jzern): full support of animation frames will require API additions. if (has_animation) { status = VP8_STATUS_UNSUPPORTED_FEATURE; } } return status; } //------------------------------------------------------------------------------ // WebPDecParams void WebPResetDecParams(WebPDecParams* const params) { if (params != NULL) { memset(params, 0, sizeof(*params)); } } //------------------------------------------------------------------------------ // "Into" decoding variants // Main flow static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size, WebPDecParams* const params) { VP8StatusCode status; VP8Io io; WebPHeaderStructure headers; headers.data = data; headers.data_size = data_size; status = WebPParseHeaders(&headers); // Process Pre-VP8 chunks. if (status != VP8_STATUS_OK) { return status; } assert(params != NULL); VP8InitIo(&io); io.data = headers.data + headers.offset; io.data_size = headers.data_size - headers.offset; WebPInitCustomIo(params, &io); // Plug the I/O functions. if (!headers.is_lossless) { VP8Decoder* const dec = VP8New(); if (dec == NULL) { return VP8_STATUS_OUT_OF_MEMORY; } dec->alpha_data_ = headers.alpha_data; dec->alpha_data_size_ = headers.alpha_data_size; // Decode bitstream header, update io->width/io->height. if (!VP8GetHeaders(dec, &io)) { status = dec->status_; // An error occurred. Grab error status. } else { // Allocate/check output buffers. status = WebPAllocateDecBuffer(io.width, io.height, params->options, params->output); if (status == VP8_STATUS_OK) { // Decode // This change must be done before calling VP8Decode() dec->mt_method_ = VP8GetThreadMethod(params->options, &headers, io.width, io.height); VP8InitDithering(params->options, dec); if (!VP8Decode(dec, &io)) { status = dec->status_; } } } VP8Delete(dec); } else { VP8LDecoder* const dec = VP8LNew(); if (dec == NULL) { return VP8_STATUS_OUT_OF_MEMORY; } if (!VP8LDecodeHeader(dec, &io)) { status = dec->status_; // An error occurred. Grab error status. } else { // Allocate/check output buffers. status = WebPAllocateDecBuffer(io.width, io.height, params->options, params->output); if (status == VP8_STATUS_OK) { // Decode if (!VP8LDecodeImage(dec)) { status = dec->status_; } } } VP8LDelete(dec); } if (status != VP8_STATUS_OK) { WebPFreeDecBuffer(params->output); } return status; } // Helpers static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace, const uint8_t* const data, size_t data_size, uint8_t* const rgba, int stride, size_t size) { WebPDecParams params; WebPDecBuffer buf; if (rgba == NULL) { return NULL; } WebPInitDecBuffer(&buf); WebPResetDecParams(¶ms); params.output = &buf; buf.colorspace = colorspace; buf.u.RGBA.rgba = rgba; buf.u.RGBA.stride = stride; buf.u.RGBA.size = size; buf.is_external_memory = 1; if (DecodeInto(data, data_size, ¶ms) != VP8_STATUS_OK) { return NULL; } return rgba; } uint8_t* WebPDecodeRGBInto(const uint8_t* data, size_t data_size, uint8_t* output, size_t size, int stride) { return DecodeIntoRGBABuffer(MODE_RGB, data, data_size, output, stride, size); } uint8_t* WebPDecodeRGBAInto(const uint8_t* data, size_t data_size, uint8_t* output, size_t size, int stride) { return DecodeIntoRGBABuffer(MODE_RGBA, data, data_size, output, stride, size); } uint8_t* WebPDecodeARGBInto(const uint8_t* data, size_t data_size, uint8_t* output, size_t size, int stride) { return DecodeIntoRGBABuffer(MODE_ARGB, data, data_size, output, stride, size); } uint8_t* WebPDecodeBGRInto(const uint8_t* data, size_t data_size, uint8_t* output, size_t size, int stride) { return DecodeIntoRGBABuffer(MODE_BGR, data, data_size, output, stride, size); } uint8_t* WebPDecodeBGRAInto(const uint8_t* data, size_t data_size, uint8_t* output, size_t size, int stride) { return DecodeIntoRGBABuffer(MODE_BGRA, data, data_size, output, stride, size); } uint8_t* WebPDecodeYUVInto(const uint8_t* data, size_t data_size, uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride) { WebPDecParams params; WebPDecBuffer output; if (luma == NULL) return NULL; WebPInitDecBuffer(&output); WebPResetDecParams(¶ms); params.output = &output; output.colorspace = MODE_YUV; output.u.YUVA.y = luma; output.u.YUVA.y_stride = luma_stride; output.u.YUVA.y_size = luma_size; output.u.YUVA.u = u; output.u.YUVA.u_stride = u_stride; output.u.YUVA.u_size = u_size; output.u.YUVA.v = v; output.u.YUVA.v_stride = v_stride; output.u.YUVA.v_size = v_size; output.is_external_memory = 1; if (DecodeInto(data, data_size, ¶ms) != VP8_STATUS_OK) { return NULL; } return luma; } //------------------------------------------------------------------------------ static uint8_t* Decode(WEBP_CSP_MODE mode, const uint8_t* const data, size_t data_size, int* const width, int* const height, WebPDecBuffer* const keep_info) { WebPDecParams params; WebPDecBuffer output; WebPInitDecBuffer(&output); WebPResetDecParams(¶ms); params.output = &output; output.colorspace = mode; // Retrieve (and report back) the required dimensions from bitstream. if (!WebPGetInfo(data, data_size, &output.width, &output.height)) { return NULL; } if (width != NULL) *width = output.width; if (height != NULL) *height = output.height; // Decode if (DecodeInto(data, data_size, ¶ms) != VP8_STATUS_OK) { return NULL; } if (keep_info != NULL) { // keep track of the side-info WebPCopyDecBuffer(&output, keep_info); } // return decoded samples (don't clear 'output'!) return WebPIsRGBMode(mode) ? output.u.RGBA.rgba : output.u.YUVA.y; } uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height) { return Decode(MODE_RGB, data, data_size, width, height, NULL); } uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, int* width, int* height) { return Decode(MODE_RGBA, data, data_size, width, height, NULL); } uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, int* width, int* height) { return Decode(MODE_ARGB, data, data_size, width, height, NULL); } uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, int* width, int* height) { return Decode(MODE_BGR, data, data_size, width, height, NULL); } uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, int* width, int* height) { return Decode(MODE_BGRA, data, data_size, width, height, NULL); } uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size, int* width, int* height, uint8_t** u, uint8_t** v, int* stride, int* uv_stride) { WebPDecBuffer output; // only to preserve the side-infos uint8_t* const out = Decode(MODE_YUV, data, data_size, width, height, &output); if (out != NULL) { const WebPYUVABuffer* const buf = &output.u.YUVA; *u = buf->u; *v = buf->v; *stride = buf->y_stride; *uv_stride = buf->u_stride; assert(buf->u_stride == buf->v_stride); } return out; } static void DefaultFeatures(WebPBitstreamFeatures* const features) { assert(features != NULL); memset(features, 0, sizeof(*features)); } static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size, WebPBitstreamFeatures* const features) { if (features == NULL || data == NULL) { return VP8_STATUS_INVALID_PARAM; } DefaultFeatures(features); // Only parse enough of the data to retrieve the features. return ParseHeadersInternal(data, data_size, &features->width, &features->height, &features->has_alpha, &features->has_animation, &features->format, NULL); } //------------------------------------------------------------------------------ // WebPGetInfo() int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height) { WebPBitstreamFeatures features; if (GetFeatures(data, data_size, &features) != VP8_STATUS_OK) { return 0; } if (width != NULL) { *width = features.width; } if (height != NULL) { *height = features.height; } return 1; } //------------------------------------------------------------------------------ // Advance decoding API int WebPInitDecoderConfigInternal(WebPDecoderConfig* config, int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { return 0; // version mismatch } if (config == NULL) { return 0; } memset(config, 0, sizeof(*config)); DefaultFeatures(&config->input); WebPInitDecBuffer(&config->output); return 1; } VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size, WebPBitstreamFeatures* features, int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { return VP8_STATUS_INVALID_PARAM; // version mismatch } if (features == NULL) { return VP8_STATUS_INVALID_PARAM; } return GetFeatures(data, data_size, features); } VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, WebPDecoderConfig* config) { WebPDecParams params; VP8StatusCode status; if (config == NULL) { return VP8_STATUS_INVALID_PARAM; } status = GetFeatures(data, data_size, &config->input); if (status != VP8_STATUS_OK) { if (status == VP8_STATUS_NOT_ENOUGH_DATA) { return VP8_STATUS_BITSTREAM_ERROR; // Not-enough-data treated as error. } return status; } WebPResetDecParams(¶ms); params.output = &config->output; params.options = &config->options; status = DecodeInto(data, data_size, ¶ms); return status; } //------------------------------------------------------------------------------ // Cropping and rescaling. int WebPIoInitFromOptions(const WebPDecoderOptions* const options, VP8Io* const io, WEBP_CSP_MODE src_colorspace) { const int W = io->width; const int H = io->height; int x = 0, y = 0, w = W, h = H; // Cropping io->use_cropping = (options != NULL) && (options->use_cropping > 0); if (io->use_cropping) { w = options->crop_width; h = options->crop_height; x = options->crop_left; y = options->crop_top; if (!WebPIsRGBMode(src_colorspace)) { // only snap for YUV420 or YUV422 x &= ~1; y &= ~1; // TODO(later): only for YUV420, not YUV422. } if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) { return 0; // out of frame boundary error } } io->crop_left = x; io->crop_top = y; io->crop_right = x + w; io->crop_bottom = y + h; io->mb_w = w; io->mb_h = h; // Scaling io->use_scaling = (options != NULL) && (options->use_scaling > 0); if (io->use_scaling) { if (options->scaled_width <= 0 || options->scaled_height <= 0) { return 0; } io->scaled_width = options->scaled_width; io->scaled_height = options->scaled_height; } // Filter io->bypass_filtering = options && options->bypass_filtering; // Fancy upsampler #ifdef FANCY_UPSAMPLING io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling); #endif if (io->use_scaling) { // disable filter (only for large downscaling ratio). io->bypass_filtering = (io->scaled_width < W * 3 / 4) && (io->scaled_height < H * 3 / 4); io->fancy_upsampling = 0; } return 1; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/vp8li.h0000644000014400001440000001077712255002107012612 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Lossless decoder: internal header. // // Author: Skal (pascal.massimino@gmail.com) // Vikas Arora(vikaas.arora@gmail.com) #ifndef WEBP_DEC_VP8LI_H_ #define WEBP_DEC_VP8LI_H_ #include // for memcpy() #include "./webpi.h" #include "../utils/bit_reader.h" #include "../utils/color_cache.h" #include "../utils/huffman.h" #include "../webp/format_constants.h" #ifdef __cplusplus extern "C" { #endif typedef enum { READ_DATA = 0, READ_HDR = 1, READ_DIM = 2 } VP8LDecodeState; typedef struct VP8LTransform VP8LTransform; struct VP8LTransform { VP8LImageTransformType type_; // transform type. int bits_; // subsampling bits defining transform window. int xsize_; // transform window X index. int ysize_; // transform window Y index. uint32_t *data_; // transform data. }; typedef struct { HuffmanTree htrees_[HUFFMAN_CODES_PER_META_CODE]; } HTreeGroup; typedef struct { int color_cache_size_; VP8LColorCache color_cache_; int huffman_mask_; int huffman_subsample_bits_; int huffman_xsize_; uint32_t *huffman_image_; int num_htree_groups_; HTreeGroup *htree_groups_; } VP8LMetadata; typedef struct VP8LDecoder VP8LDecoder; struct VP8LDecoder { VP8StatusCode status_; VP8LDecodeState action_; VP8LDecodeState state_; VP8Io *io_; const WebPDecBuffer *output_; // shortcut to io->opaque->output uint32_t *pixels_; // Internal data: either uint8_t* for alpha // or uint32_t* for BGRA. uint32_t *argb_cache_; // Scratch buffer for temporary BGRA storage. VP8LBitReader br_; int width_; int height_; int last_row_; // last input row decoded so far. int last_pixel_; // last pixel decoded so far. However, it may // not be transformed, scaled and // color-converted yet. int last_out_row_; // last row output so far. VP8LMetadata hdr_; int next_transform_; VP8LTransform transforms_[NUM_TRANSFORMS]; // or'd bitset storing the transforms types. uint32_t transforms_seen_; uint8_t *rescaler_memory; // Working memory for rescaling work. WebPRescaler *rescaler; // Common rescaler for all channels. }; //------------------------------------------------------------------------------ // internal functions. Not public. struct ALPHDecoder; // Defined in dec/alphai.h. // in vp8l.c // Decodes image header for alpha data stored using lossless compression. // Returns false in case of error. int VP8LDecodeAlphaHeader(struct ALPHDecoder* const alph_dec, const uint8_t* const data, size_t data_size, uint8_t* const output); // Decodes *at least* 'last_row' rows of alpha. If some of the initial rows are // already decoded in previous call(s), it will resume decoding from where it // was paused. // Returns false in case of bitstream error. int VP8LDecodeAlphaImageStream(struct ALPHDecoder* const alph_dec, int last_row); // Allocates and initialize a new lossless decoder instance. VP8LDecoder* VP8LNew(void); // Decodes the image header. Returns false in case of error. int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io); // Decodes an image. It's required to decode the lossless header before calling // this function. Returns false in case of error, with updated dec->status_. int VP8LDecodeImage(VP8LDecoder* const dec); // Resets the decoder in its initial state, reclaiming memory. // Preserves the dec->status_ value. void VP8LClear(VP8LDecoder* const dec); // Clears and deallocate a lossless decoder instance. void VP8LDelete(VP8LDecoder* const dec); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_DEC_VP8LI_H_ */ libwebp-0.4.0/src/dec/quant.c0000644000014400001440000000736512255002107012672 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Quantizer initialization // // Author: Skal (pascal.massimino@gmail.com) #include "./vp8i.h" static WEBP_INLINE int clip(int v, int M) { return v < 0 ? 0 : v > M ? M : v; } // Paragraph 14.1 static const uint8_t kDcTable[128] = { 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157 }; static const uint16_t kAcTable[128] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284 }; //------------------------------------------------------------------------------ // Paragraph 9.6 void VP8ParseQuant(VP8Decoder* const dec) { VP8BitReader* const br = &dec->br_; const int base_q0 = VP8GetValue(br, 7); const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0; const VP8SegmentHeader* const hdr = &dec->segment_hdr_; int i; for (i = 0; i < NUM_MB_SEGMENTS; ++i) { int q; if (hdr->use_segment_) { q = hdr->quantizer_[i]; if (!hdr->absolute_delta_) { q += base_q0; } } else { if (i > 0) { dec->dqm_[i] = dec->dqm_[0]; continue; } else { q = base_q0; } } { VP8QuantMatrix* const m = &dec->dqm_[i]; m->y1_mat_[0] = kDcTable[clip(q + dqy1_dc, 127)]; m->y1_mat_[1] = kAcTable[clip(q + 0, 127)]; m->y2_mat_[0] = kDcTable[clip(q + dqy2_dc, 127)] * 2; // For all x in [0..284], x*155/100 is bitwise equal to (x*101581) >> 16. // The smallest precision for that is '(x*6349) >> 12' but 16 is a good // word size. m->y2_mat_[1] = (kAcTable[clip(q + dqy2_ac, 127)] * 101581) >> 16; if (m->y2_mat_[1] < 8) m->y2_mat_[1] = 8; m->uv_mat_[0] = kDcTable[clip(q + dquv_dc, 117)]; m->uv_mat_[1] = kAcTable[clip(q + dquv_ac, 127)]; m->uv_quant_ = q + dquv_ac; // for dithering strength evaluation } } } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/buffer.c0000644000014400001440000001546312255002107013011 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Everything about WebPDecBuffer // // Author: Skal (pascal.massimino@gmail.com) #include #include "./vp8i.h" #include "./webpi.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ // WebPDecBuffer // Number of bytes per pixel for the different color-spaces. static const int kModeBpp[MODE_LAST] = { 3, 4, 3, 4, 4, 2, 2, 4, 4, 4, 2, // pre-multiplied modes 1, 1 }; // Check that webp_csp_mode is within the bounds of WEBP_CSP_MODE. // Convert to an integer to handle both the unsigned/signed enum cases // without the need for casting to remove type limit warnings. static int IsValidColorspace(int webp_csp_mode) { return (webp_csp_mode >= MODE_RGB && webp_csp_mode < MODE_LAST); } static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) { int ok = 1; const WEBP_CSP_MODE mode = buffer->colorspace; const int width = buffer->width; const int height = buffer->height; if (!IsValidColorspace(mode)) { ok = 0; } else if (!WebPIsRGBMode(mode)) { // YUV checks const WebPYUVABuffer* const buf = &buffer->u.YUVA; const uint64_t y_size = (uint64_t)buf->y_stride * height; const uint64_t u_size = (uint64_t)buf->u_stride * ((height + 1) / 2); const uint64_t v_size = (uint64_t)buf->v_stride * ((height + 1) / 2); const uint64_t a_size = (uint64_t)buf->a_stride * height; ok &= (y_size <= buf->y_size); ok &= (u_size <= buf->u_size); ok &= (v_size <= buf->v_size); ok &= (buf->y_stride >= width); ok &= (buf->u_stride >= (width + 1) / 2); ok &= (buf->v_stride >= (width + 1) / 2); ok &= (buf->y != NULL); ok &= (buf->u != NULL); ok &= (buf->v != NULL); if (mode == MODE_YUVA) { ok &= (buf->a_stride >= width); ok &= (a_size <= buf->a_size); ok &= (buf->a != NULL); } } else { // RGB checks const WebPRGBABuffer* const buf = &buffer->u.RGBA; const uint64_t size = (uint64_t)buf->stride * height; ok &= (size <= buf->size); ok &= (buf->stride >= width * kModeBpp[mode]); ok &= (buf->rgba != NULL); } return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM; } static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) { const int w = buffer->width; const int h = buffer->height; const WEBP_CSP_MODE mode = buffer->colorspace; if (w <= 0 || h <= 0 || !IsValidColorspace(mode)) { return VP8_STATUS_INVALID_PARAM; } if (!buffer->is_external_memory && buffer->private_memory == NULL) { uint8_t* output; int uv_stride = 0, a_stride = 0; uint64_t uv_size = 0, a_size = 0, total_size; // We need memory and it hasn't been allocated yet. // => initialize output buffer, now that dimensions are known. const int stride = w * kModeBpp[mode]; const uint64_t size = (uint64_t)stride * h; if (!WebPIsRGBMode(mode)) { uv_stride = (w + 1) / 2; uv_size = (uint64_t)uv_stride * ((h + 1) / 2); if (mode == MODE_YUVA) { a_stride = w; a_size = (uint64_t)a_stride * h; } } total_size = size + 2 * uv_size + a_size; // Security/sanity checks output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output)); if (output == NULL) { return VP8_STATUS_OUT_OF_MEMORY; } buffer->private_memory = output; if (!WebPIsRGBMode(mode)) { // YUVA initialization WebPYUVABuffer* const buf = &buffer->u.YUVA; buf->y = output; buf->y_stride = stride; buf->y_size = (size_t)size; buf->u = output + size; buf->u_stride = uv_stride; buf->u_size = (size_t)uv_size; buf->v = output + size + uv_size; buf->v_stride = uv_stride; buf->v_size = (size_t)uv_size; if (mode == MODE_YUVA) { buf->a = output + size + 2 * uv_size; } buf->a_size = (size_t)a_size; buf->a_stride = a_stride; } else { // RGBA initialization WebPRGBABuffer* const buf = &buffer->u.RGBA; buf->rgba = output; buf->stride = stride; buf->size = (size_t)size; } } return CheckDecBuffer(buffer); } VP8StatusCode WebPAllocateDecBuffer(int w, int h, const WebPDecoderOptions* const options, WebPDecBuffer* const out) { if (out == NULL || w <= 0 || h <= 0) { return VP8_STATUS_INVALID_PARAM; } if (options != NULL) { // First, apply options if there is any. if (options->use_cropping) { const int cw = options->crop_width; const int ch = options->crop_height; const int x = options->crop_left & ~1; const int y = options->crop_top & ~1; if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) { return VP8_STATUS_INVALID_PARAM; // out of frame boundary. } w = cw; h = ch; } if (options->use_scaling) { if (options->scaled_width <= 0 || options->scaled_height <= 0) { return VP8_STATUS_INVALID_PARAM; } w = options->scaled_width; h = options->scaled_height; } } out->width = w; out->height = h; // Then, allocate buffer for real return AllocateBuffer(out); } //------------------------------------------------------------------------------ // constructors / destructors int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { return 0; // version mismatch } if (buffer == NULL) return 0; memset(buffer, 0, sizeof(*buffer)); return 1; } void WebPFreeDecBuffer(WebPDecBuffer* buffer) { if (buffer != NULL) { if (!buffer->is_external_memory) free(buffer->private_memory); buffer->private_memory = NULL; } } void WebPCopyDecBuffer(const WebPDecBuffer* const src, WebPDecBuffer* const dst) { if (src != NULL && dst != NULL) { *dst = *src; if (src->private_memory != NULL) { dst->is_external_memory = 1; // dst buffer doesn't own the memory. dst->private_memory = NULL; } } } // Copy and transfer ownership from src to dst (beware of parameter order!) void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst) { if (src != NULL && dst != NULL) { *dst = *src; if (src->private_memory != NULL) { src->is_external_memory = 1; // src relinquishes ownership src->private_memory = NULL; } } } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/tree.c0000644000014400001440000005226312255002107012476 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Coding trees and probas // // Author: Skal (pascal.massimino@gmail.com) #include "vp8i.h" #define USE_GENERIC_TREE #ifdef USE_GENERIC_TREE static const int8_t kYModesIntra4[18] = { -B_DC_PRED, 1, -B_TM_PRED, 2, -B_VE_PRED, 3, 4, 6, -B_HE_PRED, 5, -B_RD_PRED, -B_VR_PRED, -B_LD_PRED, 7, -B_VL_PRED, 8, -B_HD_PRED, -B_HU_PRED }; #endif //------------------------------------------------------------------------------ // Default probabilities // Paragraph 13.5 static const uint8_t CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = { { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 }, { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 }, { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 } }, { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 }, { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 }, { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 }, }, { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 }, { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 }, { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 }, }, { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 }, { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 }, { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 } }, { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 }, { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 }, { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 } }, { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 }, { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 }, { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 } }, { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }, { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 }, { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 }, { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 } }, { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 }, { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 }, { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 } }, { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 }, { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 }, { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 } }, { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 }, { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 }, { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 } }, { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 }, { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 }, { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 } }, { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 }, { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 }, { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 } }, { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 }, { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 }, { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 } }, { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 }, { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 }, { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 } } }, { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 }, { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 }, { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 } }, { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 }, { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 }, { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 } }, { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 }, { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 }, { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 } }, { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 }, { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 }, { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 } }, { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 }, { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 }, { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 }, { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 }, { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }, { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 }, { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 }, { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 } }, { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 }, { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 }, { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 } }, { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 }, { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 }, { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 } }, { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 }, { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 }, { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 } }, { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 }, { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 }, { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 } }, { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 }, { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 }, { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 } }, { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 }, { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 }, { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 } }, { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 } } } }; // Paragraph 11.5 static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { { 231, 120, 48, 89, 115, 113, 120, 152, 112 }, { 152, 179, 64, 126, 170, 118, 46, 70, 95 }, { 175, 69, 143, 80, 85, 82, 72, 155, 103 }, { 56, 58, 10, 171, 218, 189, 17, 13, 152 }, { 114, 26, 17, 163, 44, 195, 21, 10, 173 }, { 121, 24, 80, 195, 26, 62, 44, 64, 85 }, { 144, 71, 10, 38, 171, 213, 144, 34, 26 }, { 170, 46, 55, 19, 136, 160, 33, 206, 71 }, { 63, 20, 8, 114, 114, 208, 12, 9, 226 }, { 81, 40, 11, 96, 182, 84, 29, 16, 36 } }, { { 134, 183, 89, 137, 98, 101, 106, 165, 148 }, { 72, 187, 100, 130, 157, 111, 32, 75, 80 }, { 66, 102, 167, 99, 74, 62, 40, 234, 128 }, { 41, 53, 9, 178, 241, 141, 26, 8, 107 }, { 74, 43, 26, 146, 73, 166, 49, 23, 157 }, { 65, 38, 105, 160, 51, 52, 31, 115, 128 }, { 104, 79, 12, 27, 217, 255, 87, 17, 7 }, { 87, 68, 71, 44, 114, 51, 15, 186, 23 }, { 47, 41, 14, 110, 182, 183, 21, 17, 194 }, { 66, 45, 25, 102, 197, 189, 23, 18, 22 } }, { { 88, 88, 147, 150, 42, 46, 45, 196, 205 }, { 43, 97, 183, 117, 85, 38, 35, 179, 61 }, { 39, 53, 200, 87, 26, 21, 43, 232, 171 }, { 56, 34, 51, 104, 114, 102, 29, 93, 77 }, { 39, 28, 85, 171, 58, 165, 90, 98, 64 }, { 34, 22, 116, 206, 23, 34, 43, 166, 73 }, { 107, 54, 32, 26, 51, 1, 81, 43, 31 }, { 68, 25, 106, 22, 64, 171, 36, 225, 114 }, { 34, 19, 21, 102, 132, 188, 16, 76, 124 }, { 62, 18, 78, 95, 85, 57, 50, 48, 51 } }, { { 193, 101, 35, 159, 215, 111, 89, 46, 111 }, { 60, 148, 31, 172, 219, 228, 21, 18, 111 }, { 112, 113, 77, 85, 179, 255, 38, 120, 114 }, { 40, 42, 1, 196, 245, 209, 10, 25, 109 }, { 88, 43, 29, 140, 166, 213, 37, 43, 154 }, { 61, 63, 30, 155, 67, 45, 68, 1, 209 }, { 100, 80, 8, 43, 154, 1, 51, 26, 71 }, { 142, 78, 78, 16, 255, 128, 34, 197, 171 }, { 41, 40, 5, 102, 211, 183, 4, 1, 221 }, { 51, 50, 17, 168, 209, 192, 23, 25, 82 } }, { { 138, 31, 36, 171, 27, 166, 38, 44, 229 }, { 67, 87, 58, 169, 82, 115, 26, 59, 179 }, { 63, 59, 90, 180, 59, 166, 93, 73, 154 }, { 40, 40, 21, 116, 143, 209, 34, 39, 175 }, { 47, 15, 16, 183, 34, 223, 49, 45, 183 }, { 46, 17, 33, 183, 6, 98, 15, 32, 183 }, { 57, 46, 22, 24, 128, 1, 54, 17, 37 }, { 65, 32, 73, 115, 28, 128, 23, 128, 205 }, { 40, 3, 9, 115, 51, 192, 18, 6, 223 }, { 87, 37, 9, 115, 59, 77, 64, 21, 47 } }, { { 104, 55, 44, 218, 9, 54, 53, 130, 226 }, { 64, 90, 70, 205, 40, 41, 23, 26, 57 }, { 54, 57, 112, 184, 5, 41, 38, 166, 213 }, { 30, 34, 26, 133, 152, 116, 10, 32, 134 }, { 39, 19, 53, 221, 26, 114, 32, 73, 255 }, { 31, 9, 65, 234, 2, 15, 1, 118, 73 }, { 75, 32, 12, 51, 192, 255, 160, 43, 51 }, { 88, 31, 35, 67, 102, 85, 55, 186, 85 }, { 56, 21, 23, 111, 59, 205, 45, 37, 192 }, { 55, 38, 70, 124, 73, 102, 1, 34, 98 } }, { { 125, 98, 42, 88, 104, 85, 117, 175, 82 }, { 95, 84, 53, 89, 128, 100, 113, 101, 45 }, { 75, 79, 123, 47, 51, 128, 81, 171, 1 }, { 57, 17, 5, 71, 102, 57, 53, 41, 49 }, { 38, 33, 13, 121, 57, 73, 26, 1, 85 }, { 41, 10, 67, 138, 77, 110, 90, 47, 114 }, { 115, 21, 2, 10, 102, 255, 166, 23, 6 }, { 101, 29, 16, 10, 85, 128, 101, 196, 26 }, { 57, 18, 10, 102, 102, 213, 34, 20, 43 }, { 117, 20, 15, 36, 163, 128, 68, 1, 26 } }, { { 102, 61, 71, 37, 34, 53, 31, 243, 192 }, { 69, 60, 71, 38, 73, 119, 28, 222, 37 }, { 68, 45, 128, 34, 1, 47, 11, 245, 171 }, { 62, 17, 19, 70, 146, 85, 55, 62, 70 }, { 37, 43, 37, 154, 100, 163, 85, 160, 1 }, { 63, 9, 92, 136, 28, 64, 32, 201, 85 }, { 75, 15, 9, 9, 64, 255, 184, 119, 16 }, { 86, 6, 28, 5, 64, 255, 25, 248, 1 }, { 56, 8, 17, 132, 137, 255, 55, 116, 128 }, { 58, 15, 20, 82, 135, 57, 26, 121, 40 } }, { { 164, 50, 31, 137, 154, 133, 25, 35, 218 }, { 51, 103, 44, 131, 131, 123, 31, 6, 158 }, { 86, 40, 64, 135, 148, 224, 45, 183, 128 }, { 22, 26, 17, 131, 240, 154, 14, 1, 209 }, { 45, 16, 21, 91, 64, 222, 7, 1, 197 }, { 56, 21, 39, 155, 60, 138, 23, 102, 213 }, { 83, 12, 13, 54, 192, 255, 68, 47, 28 }, { 85, 26, 85, 85, 128, 128, 32, 146, 171 }, { 18, 11, 7, 63, 144, 171, 4, 4, 246 }, { 35, 27, 10, 146, 174, 171, 12, 26, 128 } }, { { 190, 80, 35, 99, 180, 80, 126, 54, 45 }, { 85, 126, 47, 87, 176, 51, 41, 20, 32 }, { 101, 75, 128, 139, 118, 146, 116, 128, 85 }, { 56, 41, 15, 176, 236, 85, 37, 9, 62 }, { 71, 30, 17, 119, 118, 255, 17, 18, 138 }, { 101, 38, 60, 138, 55, 70, 43, 26, 142 }, { 146, 36, 19, 30, 171, 255, 97, 27, 20 }, { 138, 45, 61, 62, 219, 1, 81, 188, 64 }, { 32, 41, 20, 117, 151, 142, 20, 21, 163 }, { 112, 19, 12, 61, 195, 128, 48, 4, 24 } } }; void VP8ResetProba(VP8Proba* const proba) { memset(proba->segments_, 255u, sizeof(proba->segments_)); // proba->bands_[][] is initialized later } void VP8ParseIntraMode(VP8BitReader* const br, VP8Decoder* const dec) { uint8_t* const top = dec->intra_t_ + 4 * dec->mb_x_; uint8_t* const left = dec->intra_l_; VP8MBData* const block = dec->mb_data_ + dec->mb_x_; block->is_i4x4_ = !VP8GetBit(br, 145); // decide for B_PRED first if (!block->is_i4x4_) { // Hardcoded 16x16 intra-mode decision tree. const int ymode = VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED) : (VP8GetBit(br, 163) ? V_PRED : DC_PRED); block->imodes_[0] = ymode; memset(top, ymode, 4 * sizeof(*top)); memset(left, ymode, 4 * sizeof(*left)); } else { uint8_t* modes = block->imodes_; int y; for (y = 0; y < 4; ++y) { int ymode = left[y]; int x; for (x = 0; x < 4; ++x) { const uint8_t* const prob = kBModesProba[top[x]][ymode]; #ifdef USE_GENERIC_TREE // Generic tree-parsing int i = kYModesIntra4[VP8GetBit(br, prob[0])]; while (i > 0) { i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])]; } ymode = -i; #else // Hardcoded tree parsing ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED : !VP8GetBit(br, prob[1]) ? B_TM_PRED : !VP8GetBit(br, prob[2]) ? B_VE_PRED : !VP8GetBit(br, prob[3]) ? (!VP8GetBit(br, prob[4]) ? B_HE_PRED : (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) : (!VP8GetBit(br, prob[6]) ? B_LD_PRED : (!VP8GetBit(br, prob[7]) ? B_VL_PRED : (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED))); #endif // USE_GENERIC_TREE top[x] = ymode; } memcpy(modes, top, 4 * sizeof(*top)); modes += 4; left[y] = ymode; } } // Hardcoded UVMode decision tree block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED : !VP8GetBit(br, 114) ? V_PRED : VP8GetBit(br, 183) ? TM_PRED : H_PRED; } //------------------------------------------------------------------------------ // Paragraph 13 static const uint8_t CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = { { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 }, { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 }, { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 } }, { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 }, { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 }, { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 } }, { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 }, { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 } }, { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } } }; // Paragraph 9.9 void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) { VP8Proba* const proba = &dec->proba_; int t, b, c, p; for (t = 0; t < NUM_TYPES; ++t) { for (b = 0; b < NUM_BANDS; ++b) { for (c = 0; c < NUM_CTX; ++c) { for (p = 0; p < NUM_PROBAS; ++p) { const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ? VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p]; proba->bands_[t][b].probas_[c][p] = v; } } } } dec->use_skip_proba_ = VP8Get(br); if (dec->use_skip_proba_) { dec->skip_p_ = VP8GetValue(br, 8); } } libwebp-0.4.0/src/dec/vp8i.h0000644000014400001440000003017412255002107012427 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // VP8 decoder: internal header. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_DEC_VP8I_H_ #define WEBP_DEC_VP8I_H_ #include // for memcpy() #include "./vp8li.h" #include "../utils/bit_reader.h" #include "../utils/random.h" #include "../utils/thread.h" #include "../dsp/dsp.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Various defines and enums // version numbers #define DEC_MAJ_VERSION 0 #define DEC_MIN_VERSION 4 #define DEC_REV_VERSION 0 // intra prediction modes enum { B_DC_PRED = 0, // 4x4 modes B_TM_PRED, B_VE_PRED, B_HE_PRED, B_RD_PRED, B_VR_PRED, B_LD_PRED, B_VL_PRED, B_HD_PRED, B_HU_PRED, NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED, // = 10 // Luma16 or UV modes DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED, H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED, B_PRED = NUM_BMODES, // refined I4x4 mode // special modes B_DC_PRED_NOTOP = 4, B_DC_PRED_NOLEFT = 5, B_DC_PRED_NOTOPLEFT = 6, NUM_B_DC_MODES = 7 }; enum { MB_FEATURE_TREE_PROBS = 3, NUM_MB_SEGMENTS = 4, NUM_REF_LF_DELTAS = 4, NUM_MODE_LF_DELTAS = 4, // I4x4, ZERO, *, SPLIT MAX_NUM_PARTITIONS = 8, // Probabilities NUM_TYPES = 4, NUM_BANDS = 8, NUM_CTX = 3, NUM_PROBAS = 11, NUM_MV_PROBAS = 19 }; // YUV-cache parameters. // Constraints are: We need to store one 16x16 block of luma samples (y), // and two 8x8 chroma blocks (u/v). These are better be 16-bytes aligned, // in order to be SIMD-friendly. We also need to store the top, left and // top-left samples (from previously decoded blocks), along with four // extra top-right samples for luma (intra4x4 prediction only). // One possible layout is, using 32 * (17 + 9) bytes: // // .+------ <- only 1 pixel high // .|yyyyt. // .|yyyyt. // .|yyyyt. // .|yyyy.. // .+--.+-- <- only 1 pixel high // .|uu.|vv // .|uu.|vv // // Every character is a 4x4 block, with legend: // '.' = unused // 'y' = y-samples 'u' = u-samples 'v' = u-samples // '|' = left sample, '-' = top sample, '+' = top-left sample // 't' = extra top-right sample for 4x4 modes // With this layout, BPS (=Bytes Per Scan-line) is one cacheline size. #define BPS 32 // this is the common stride used by yuv[] #define YUV_SIZE (BPS * 17 + BPS * 9) #define Y_SIZE (BPS * 17) #define Y_OFF (BPS * 1 + 8) #define U_OFF (Y_OFF + BPS * 16 + BPS) #define V_OFF (U_OFF + 16) // minimal width under which lossy multi-threading is always disabled #define MIN_WIDTH_FOR_THREADS 512 //------------------------------------------------------------------------------ // Headers typedef struct { uint8_t key_frame_; uint8_t profile_; uint8_t show_; uint32_t partition_length_; } VP8FrameHeader; typedef struct { uint16_t width_; uint16_t height_; uint8_t xscale_; uint8_t yscale_; uint8_t colorspace_; // 0 = YCbCr uint8_t clamp_type_; } VP8PictureHeader; // segment features typedef struct { int use_segment_; int update_map_; // whether to update the segment map or not int absolute_delta_; // absolute or delta values for quantizer and filter int8_t quantizer_[NUM_MB_SEGMENTS]; // quantization changes int8_t filter_strength_[NUM_MB_SEGMENTS]; // filter strength for segments } VP8SegmentHeader; // probas associated to one of the contexts typedef uint8_t VP8ProbaArray[NUM_PROBAS]; typedef struct { // all the probas associated to one band VP8ProbaArray probas_[NUM_CTX]; } VP8BandProbas; // Struct collecting all frame-persistent probabilities. typedef struct { uint8_t segments_[MB_FEATURE_TREE_PROBS]; // Type: 0:Intra16-AC 1:Intra16-DC 2:Chroma 3:Intra4 VP8BandProbas bands_[NUM_TYPES][NUM_BANDS]; } VP8Proba; // Filter parameters typedef struct { int simple_; // 0=complex, 1=simple int level_; // [0..63] int sharpness_; // [0..7] int use_lf_delta_; int ref_lf_delta_[NUM_REF_LF_DELTAS]; int mode_lf_delta_[NUM_MODE_LF_DELTAS]; } VP8FilterHeader; //------------------------------------------------------------------------------ // Informations about the macroblocks. typedef struct { // filter specs uint8_t f_limit_; // filter limit in [3..189], or 0 if no filtering uint8_t f_ilevel_; // inner limit in [1..63] uint8_t f_inner_; // do inner filtering? uint8_t hev_thresh_; // high edge variance threshold in [0..2] } VP8FInfo; typedef struct { // Top/Left Contexts used for syntax-parsing uint8_t nz_; // non-zero AC/DC coeffs (4bit for luma + 4bit for chroma) uint8_t nz_dc_; // non-zero DC coeff (1bit) } VP8MB; // Dequantization matrices typedef int quant_t[2]; // [DC / AC]. Can be 'uint16_t[2]' too (~slower). typedef struct { quant_t y1_mat_, y2_mat_, uv_mat_; int uv_quant_; // U/V quantizer value int dither_; // dithering amplitude (0 = off, max=255) } VP8QuantMatrix; // Data needed to reconstruct a macroblock typedef struct { int16_t coeffs_[384]; // 384 coeffs = (16+4+4) * 4*4 uint8_t is_i4x4_; // true if intra4x4 uint8_t imodes_[16]; // one 16x16 mode (#0) or sixteen 4x4 modes uint8_t uvmode_; // chroma prediction mode // bit-wise info about the content of each sub-4x4 blocks (in decoding order). // Each of the 4x4 blocks for y/u/v is associated with a 2b code according to: // code=0 -> no coefficient // code=1 -> only DC // code=2 -> first three coefficients are non-zero // code=3 -> more than three coefficients are non-zero // This allows to call specialized transform functions. uint32_t non_zero_y_; uint32_t non_zero_uv_; uint8_t dither_; // local dithering strength (deduced from non_zero_*) } VP8MBData; // Persistent information needed by the parallel processing typedef struct { int id_; // cache row to process (in [0..2]) int mb_y_; // macroblock position of the row int filter_row_; // true if row-filtering is needed VP8FInfo* f_info_; // filter strengths (swapped with dec->f_info_) VP8MBData* mb_data_; // reconstruction data (swapped with dec->mb_data_) VP8Io io_; // copy of the VP8Io to pass to put() } VP8ThreadContext; // Saved top samples, per macroblock. Fits into a cache-line. typedef struct { uint8_t y[16], u[8], v[8]; } VP8TopSamples; //------------------------------------------------------------------------------ // VP8Decoder: the main opaque structure handed over to user struct VP8Decoder { VP8StatusCode status_; int ready_; // true if ready to decode a picture with VP8Decode() const char* error_msg_; // set when status_ is not OK. // Main data source VP8BitReader br_; // headers VP8FrameHeader frm_hdr_; VP8PictureHeader pic_hdr_; VP8FilterHeader filter_hdr_; VP8SegmentHeader segment_hdr_; // Worker WebPWorker worker_; int mt_method_; // multi-thread method: 0=off, 1=[parse+recon][filter] // 2=[parse][recon+filter] int cache_id_; // current cache row int num_caches_; // number of cached rows of 16 pixels (1, 2 or 3) VP8ThreadContext thread_ctx_; // Thread context // dimension, in macroblock units. int mb_w_, mb_h_; // Macroblock to process/filter, depending on cropping and filter_type. int tl_mb_x_, tl_mb_y_; // top-left MB that must be in-loop filtered int br_mb_x_, br_mb_y_; // last bottom-right MB that must be decoded // number of partitions. int num_parts_; // per-partition boolean decoders. VP8BitReader parts_[MAX_NUM_PARTITIONS]; // Dithering strength, deduced from decoding options int dither_; // whether to use dithering or not VP8Random dithering_rg_; // random generator for dithering // dequantization (one set of DC/AC dequant factor per segment) VP8QuantMatrix dqm_[NUM_MB_SEGMENTS]; // probabilities VP8Proba proba_; int use_skip_proba_; uint8_t skip_p_; // Boundary data cache and persistent buffers. uint8_t* intra_t_; // top intra modes values: 4 * mb_w_ uint8_t intra_l_[4]; // left intra modes values uint8_t segment_; // segment of the currently parsed block VP8TopSamples* yuv_t_; // top y/u/v samples VP8MB* mb_info_; // contextual macroblock info (mb_w_ + 1) VP8FInfo* f_info_; // filter strength info uint8_t* yuv_b_; // main block for Y/U/V (size = YUV_SIZE) uint8_t* cache_y_; // macroblock row for storing unfiltered samples uint8_t* cache_u_; uint8_t* cache_v_; int cache_y_stride_; int cache_uv_stride_; // main memory chunk for the above data. Persistent. void* mem_; size_t mem_size_; // Per macroblock non-persistent infos. int mb_x_, mb_y_; // current position, in macroblock units VP8MBData* mb_data_; // parsed reconstruction data // Filtering side-info int filter_type_; // 0=off, 1=simple, 2=complex VP8FInfo fstrengths_[NUM_MB_SEGMENTS][2]; // precalculated per-segment/type // Alpha struct ALPHDecoder* alph_dec_; // alpha-plane decoder object const uint8_t* alpha_data_; // compressed alpha data (if present) size_t alpha_data_size_; int is_alpha_decoded_; // true if alpha_data_ is decoded in alpha_plane_ uint8_t* alpha_plane_; // output. Persistent, contains the whole data. // extensions int layer_colorspace_; const uint8_t* layer_data_; // compressed layer data (if present) size_t layer_data_size_; }; //------------------------------------------------------------------------------ // internal functions. Not public. // in vp8.c int VP8SetError(VP8Decoder* const dec, VP8StatusCode error, const char* const msg); // in tree.c void VP8ResetProba(VP8Proba* const proba); void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec); void VP8ParseIntraMode(VP8BitReader* const br, VP8Decoder* const dec); // in quant.c void VP8ParseQuant(VP8Decoder* const dec); // in frame.c int VP8InitFrame(VP8Decoder* const dec, VP8Io* io); // Call io->setup() and finish setting up scan parameters. // After this call returns, one must always call VP8ExitCritical() with the // same parameters. Both functions should be used in pair. Returns VP8_STATUS_OK // if ok, otherwise sets and returns the error status on *dec. VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io); // Must always be called in pair with VP8EnterCritical(). // Returns false in case of error. int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io); // Return the multi-threading method to use (0=off), depending // on options and bitstream size. Only for lossy decoding. int VP8GetThreadMethod(const WebPDecoderOptions* const options, const WebPHeaderStructure* const headers, int width, int height); // Initialize dithering post-process if needed. void VP8InitDithering(const WebPDecoderOptions* const options, VP8Decoder* const dec); // Process the last decoded row (filtering + output). int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io); // To be called at the start of a new scanline, to initialize predictors. void VP8InitScanline(VP8Decoder* const dec); // Decode one macroblock. Returns false if there is not enough data. int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br); // in alpha.c const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec, int row, int num_rows); // in layer.c int VP8DecodeLayer(VP8Decoder* const dec); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_DEC_VP8I_H_ */ libwebp-0.4.0/src/dec/frame.c0000644000014400001440000007044412255002107012632 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Frame-reconstruction function. Memory allocation. // // Author: Skal (pascal.massimino@gmail.com) #include #include "./vp8i.h" #include "../utils/utils.h" #define ALIGN_MASK (32 - 1) static void ReconstructRow(const VP8Decoder* const dec, const VP8ThreadContext* ctx); // TODO(skal): remove //------------------------------------------------------------------------------ // Filtering // kFilterExtraRows[] = How many extra lines are needed on the MB boundary // for caching, given a filtering level. // Simple filter: up to 2 luma samples are read and 1 is written. // Complex filter: up to 4 luma samples are read and 3 are written. Same for // U/V, so it's 8 samples total (because of the 2x upsampling). static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 }; static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) { const VP8ThreadContext* const ctx = &dec->thread_ctx_; const int cache_id = ctx->id_; const int y_bps = dec->cache_y_stride_; const VP8FInfo* const f_info = ctx->f_info_ + mb_x; uint8_t* const y_dst = dec->cache_y_ + cache_id * 16 * y_bps + mb_x * 16; const int ilevel = f_info->f_ilevel_; const int limit = f_info->f_limit_; if (limit == 0) { return; } assert(limit >= 3); if (dec->filter_type_ == 1) { // simple if (mb_x > 0) { VP8SimpleHFilter16(y_dst, y_bps, limit + 4); } if (f_info->f_inner_) { VP8SimpleHFilter16i(y_dst, y_bps, limit); } if (mb_y > 0) { VP8SimpleVFilter16(y_dst, y_bps, limit + 4); } if (f_info->f_inner_) { VP8SimpleVFilter16i(y_dst, y_bps, limit); } } else { // complex const int uv_bps = dec->cache_uv_stride_; uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8; uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8; const int hev_thresh = f_info->hev_thresh_; if (mb_x > 0) { VP8HFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh); VP8HFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh); } if (f_info->f_inner_) { VP8HFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh); VP8HFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh); } if (mb_y > 0) { VP8VFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh); VP8VFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh); } if (f_info->f_inner_) { VP8VFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh); VP8VFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh); } } } // Filter the decoded macroblock row (if needed) static void FilterRow(const VP8Decoder* const dec) { int mb_x; const int mb_y = dec->thread_ctx_.mb_y_; assert(dec->thread_ctx_.filter_row_); for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) { DoFilter(dec, mb_x, mb_y); } } //------------------------------------------------------------------------------ // Precompute the filtering strength for each segment and each i4x4/i16x16 mode. static void PrecomputeFilterStrengths(VP8Decoder* const dec) { if (dec->filter_type_ > 0) { int s; const VP8FilterHeader* const hdr = &dec->filter_hdr_; for (s = 0; s < NUM_MB_SEGMENTS; ++s) { int i4x4; // First, compute the initial level int base_level; if (dec->segment_hdr_.use_segment_) { base_level = dec->segment_hdr_.filter_strength_[s]; if (!dec->segment_hdr_.absolute_delta_) { base_level += hdr->level_; } } else { base_level = hdr->level_; } for (i4x4 = 0; i4x4 <= 1; ++i4x4) { VP8FInfo* const info = &dec->fstrengths_[s][i4x4]; int level = base_level; if (hdr->use_lf_delta_) { // TODO(skal): only CURRENT is handled for now. level += hdr->ref_lf_delta_[0]; if (i4x4) { level += hdr->mode_lf_delta_[0]; } } level = (level < 0) ? 0 : (level > 63) ? 63 : level; if (level > 0) { int ilevel = level; if (hdr->sharpness_ > 0) { if (hdr->sharpness_ > 4) { ilevel >>= 2; } else { ilevel >>= 1; } if (ilevel > 9 - hdr->sharpness_) { ilevel = 9 - hdr->sharpness_; } } if (ilevel < 1) ilevel = 1; info->f_ilevel_ = ilevel; info->f_limit_ = 2 * level + ilevel; info->hev_thresh_ = (level >= 40) ? 2 : (level >= 15) ? 1 : 0; } else { info->f_limit_ = 0; // no filtering } info->f_inner_ = i4x4; } } } } //------------------------------------------------------------------------------ // Dithering #define DITHER_AMP_TAB_SIZE 12 static const int kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = { // roughly, it's dqm->uv_mat_[1] 8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1 }; void VP8InitDithering(const WebPDecoderOptions* const options, VP8Decoder* const dec) { assert(dec != NULL); if (options != NULL) { const int d = options->dithering_strength; const int max_amp = (1 << VP8_RANDOM_DITHER_FIX) - 1; const int f = (d < 0) ? 0 : (d > 100) ? max_amp : (d * max_amp / 100); if (f > 0) { int s; int all_amp = 0; for (s = 0; s < NUM_MB_SEGMENTS; ++s) { VP8QuantMatrix* const dqm = &dec->dqm_[s]; if (dqm->uv_quant_ < DITHER_AMP_TAB_SIZE) { // TODO(skal): should we specially dither more for uv_quant_ < 0? const int idx = (dqm->uv_quant_ < 0) ? 0 : dqm->uv_quant_; dqm->dither_ = (f * kQuantToDitherAmp[idx]) >> 3; } all_amp |= dqm->dither_; } if (all_amp != 0) { VP8InitRandom(&dec->dithering_rg_, 1.0f); dec->dither_ = 1; } } } } // minimal amp that will provide a non-zero dithering effect #define MIN_DITHER_AMP 4 #define DITHER_DESCALE 4 #define DITHER_DESCALE_ROUNDER (1 << (DITHER_DESCALE - 1)) #define DITHER_AMP_BITS 8 #define DITHER_AMP_CENTER (1 << DITHER_AMP_BITS) static void Dither8x8(VP8Random* const rg, uint8_t* dst, int bps, int amp) { int i, j; for (j = 0; j < 8; ++j) { for (i = 0; i < 8; ++i) { // TODO: could be made faster with SSE2 const int bits = VP8RandomBits2(rg, DITHER_AMP_BITS + 1, amp) - DITHER_AMP_CENTER; // Convert to range: [-2,2] for dither=50, [-4,4] for dither=100 const int delta = (bits + DITHER_DESCALE_ROUNDER) >> DITHER_DESCALE; const int v = (int)dst[i] + delta; dst[i] = (v < 0) ? 0 : (v > 255) ? 255u : (uint8_t)v; } dst += bps; } } static void DitherRow(VP8Decoder* const dec) { int mb_x; assert(dec->dither_); for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) { const VP8ThreadContext* const ctx = &dec->thread_ctx_; const VP8MBData* const data = ctx->mb_data_ + mb_x; const int cache_id = ctx->id_; const int uv_bps = dec->cache_uv_stride_; if (data->dither_ >= MIN_DITHER_AMP) { uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8; uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8; Dither8x8(&dec->dithering_rg_, u_dst, uv_bps, data->dither_); Dither8x8(&dec->dithering_rg_, v_dst, uv_bps, data->dither_); } } } //------------------------------------------------------------------------------ // This function is called after a row of macroblocks is finished decoding. // It also takes into account the following restrictions: // * In case of in-loop filtering, we must hold off sending some of the bottom // pixels as they are yet unfiltered. They will be when the next macroblock // row is decoded. Meanwhile, we must preserve them by rotating them in the // cache area. This doesn't hold for the very bottom row of the uncropped // picture of course. // * we must clip the remaining pixels against the cropping area. The VP8Io // struct must have the following fields set correctly before calling put(): #define MACROBLOCK_VPOS(mb_y) ((mb_y) * 16) // vertical position of a MB // Finalize and transmit a complete row. Return false in case of user-abort. static int FinishRow(VP8Decoder* const dec, VP8Io* const io) { int ok = 1; const VP8ThreadContext* const ctx = &dec->thread_ctx_; const int cache_id = ctx->id_; const int extra_y_rows = kFilterExtraRows[dec->filter_type_]; const int ysize = extra_y_rows * dec->cache_y_stride_; const int uvsize = (extra_y_rows / 2) * dec->cache_uv_stride_; const int y_offset = cache_id * 16 * dec->cache_y_stride_; const int uv_offset = cache_id * 8 * dec->cache_uv_stride_; uint8_t* const ydst = dec->cache_y_ - ysize + y_offset; uint8_t* const udst = dec->cache_u_ - uvsize + uv_offset; uint8_t* const vdst = dec->cache_v_ - uvsize + uv_offset; const int mb_y = ctx->mb_y_; const int is_first_row = (mb_y == 0); const int is_last_row = (mb_y >= dec->br_mb_y_ - 1); if (dec->mt_method_ == 2) { ReconstructRow(dec, ctx); } if (ctx->filter_row_) { FilterRow(dec); } if (dec->dither_) { DitherRow(dec); } if (io->put != NULL) { int y_start = MACROBLOCK_VPOS(mb_y); int y_end = MACROBLOCK_VPOS(mb_y + 1); if (!is_first_row) { y_start -= extra_y_rows; io->y = ydst; io->u = udst; io->v = vdst; } else { io->y = dec->cache_y_ + y_offset; io->u = dec->cache_u_ + uv_offset; io->v = dec->cache_v_ + uv_offset; } if (!is_last_row) { y_end -= extra_y_rows; } if (y_end > io->crop_bottom) { y_end = io->crop_bottom; // make sure we don't overflow on last row. } io->a = NULL; if (dec->alpha_data_ != NULL && y_start < y_end) { // TODO(skal): testing presence of alpha with dec->alpha_data_ is not a // good idea. io->a = VP8DecompressAlphaRows(dec, y_start, y_end - y_start); if (io->a == NULL) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "Could not decode alpha data."); } } if (y_start < io->crop_top) { const int delta_y = io->crop_top - y_start; y_start = io->crop_top; assert(!(delta_y & 1)); io->y += dec->cache_y_stride_ * delta_y; io->u += dec->cache_uv_stride_ * (delta_y >> 1); io->v += dec->cache_uv_stride_ * (delta_y >> 1); if (io->a != NULL) { io->a += io->width * delta_y; } } if (y_start < y_end) { io->y += io->crop_left; io->u += io->crop_left >> 1; io->v += io->crop_left >> 1; if (io->a != NULL) { io->a += io->crop_left; } io->mb_y = y_start - io->crop_top; io->mb_w = io->crop_right - io->crop_left; io->mb_h = y_end - y_start; ok = io->put(io); } } // rotate top samples if needed if (cache_id + 1 == dec->num_caches_) { if (!is_last_row) { memcpy(dec->cache_y_ - ysize, ydst + 16 * dec->cache_y_stride_, ysize); memcpy(dec->cache_u_ - uvsize, udst + 8 * dec->cache_uv_stride_, uvsize); memcpy(dec->cache_v_ - uvsize, vdst + 8 * dec->cache_uv_stride_, uvsize); } } return ok; } #undef MACROBLOCK_VPOS //------------------------------------------------------------------------------ int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io) { int ok = 1; VP8ThreadContext* const ctx = &dec->thread_ctx_; const int filter_row = (dec->filter_type_ > 0) && (dec->mb_y_ >= dec->tl_mb_y_) && (dec->mb_y_ <= dec->br_mb_y_); if (dec->mt_method_ == 0) { // ctx->id_ and ctx->f_info_ are already set ctx->mb_y_ = dec->mb_y_; ctx->filter_row_ = filter_row; ReconstructRow(dec, ctx); ok = FinishRow(dec, io); } else { WebPWorker* const worker = &dec->worker_; // Finish previous job *before* updating context ok &= WebPWorkerSync(worker); assert(worker->status_ == OK); if (ok) { // spawn a new deblocking/output job ctx->io_ = *io; ctx->id_ = dec->cache_id_; ctx->mb_y_ = dec->mb_y_; ctx->filter_row_ = filter_row; if (dec->mt_method_ == 2) { // swap macroblock data VP8MBData* const tmp = ctx->mb_data_; ctx->mb_data_ = dec->mb_data_; dec->mb_data_ = tmp; } else { // perform reconstruction directly in main thread ReconstructRow(dec, ctx); } if (filter_row) { // swap filter info VP8FInfo* const tmp = ctx->f_info_; ctx->f_info_ = dec->f_info_; dec->f_info_ = tmp; } WebPWorkerLaunch(worker); // (reconstruct)+filter in parallel if (++dec->cache_id_ == dec->num_caches_) { dec->cache_id_ = 0; } } } return ok; } //------------------------------------------------------------------------------ // Finish setting up the decoding parameter once user's setup() is called. VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) { // Call setup() first. This may trigger additional decoding features on 'io'. // Note: Afterward, we must call teardown() no matter what. if (io->setup != NULL && !io->setup(io)) { VP8SetError(dec, VP8_STATUS_USER_ABORT, "Frame setup failed"); return dec->status_; } // Disable filtering per user request if (io->bypass_filtering) { dec->filter_type_ = 0; } // TODO(skal): filter type / strength / sharpness forcing // Define the area where we can skip in-loop filtering, in case of cropping. // // 'Simple' filter reads two luma samples outside of the macroblock // and filters one. It doesn't filter the chroma samples. Hence, we can // avoid doing the in-loop filtering before crop_top/crop_left position. // For the 'Complex' filter, 3 samples are read and up to 3 are filtered. // Means: there's a dependency chain that goes all the way up to the // top-left corner of the picture (MB #0). We must filter all the previous // macroblocks. // TODO(skal): add an 'approximate_decoding' option, that won't produce // a 1:1 bit-exactness for complex filtering? { const int extra_pixels = kFilterExtraRows[dec->filter_type_]; if (dec->filter_type_ == 2) { // For complex filter, we need to preserve the dependency chain. dec->tl_mb_x_ = 0; dec->tl_mb_y_ = 0; } else { // For simple filter, we can filter only the cropped region. // We include 'extra_pixels' on the other side of the boundary, since // vertical or horizontal filtering of the previous macroblock can // modify some abutting pixels. dec->tl_mb_x_ = (io->crop_left - extra_pixels) >> 4; dec->tl_mb_y_ = (io->crop_top - extra_pixels) >> 4; if (dec->tl_mb_x_ < 0) dec->tl_mb_x_ = 0; if (dec->tl_mb_y_ < 0) dec->tl_mb_y_ = 0; } // We need some 'extra' pixels on the right/bottom. dec->br_mb_y_ = (io->crop_bottom + 15 + extra_pixels) >> 4; dec->br_mb_x_ = (io->crop_right + 15 + extra_pixels) >> 4; if (dec->br_mb_x_ > dec->mb_w_) { dec->br_mb_x_ = dec->mb_w_; } if (dec->br_mb_y_ > dec->mb_h_) { dec->br_mb_y_ = dec->mb_h_; } } PrecomputeFilterStrengths(dec); return VP8_STATUS_OK; } int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io) { int ok = 1; if (dec->mt_method_ > 0) { ok = WebPWorkerSync(&dec->worker_); } if (io->teardown != NULL) { io->teardown(io); } return ok; } //------------------------------------------------------------------------------ // For multi-threaded decoding we need to use 3 rows of 16 pixels as delay line. // // Reason is: the deblocking filter cannot deblock the bottom horizontal edges // immediately, and needs to wait for first few rows of the next macroblock to // be decoded. Hence, deblocking is lagging behind by 4 or 8 pixels (depending // on strength). // With two threads, the vertical positions of the rows being decoded are: // Decode: [ 0..15][16..31][32..47][48..63][64..79][... // Deblock: [ 0..11][12..27][28..43][44..59][... // If we use two threads and two caches of 16 pixels, the sequence would be: // Decode: [ 0..15][16..31][ 0..15!!][16..31][ 0..15][... // Deblock: [ 0..11][12..27!!][-4..11][12..27][... // The problem occurs during row [12..15!!] that both the decoding and // deblocking threads are writing simultaneously. // With 3 cache lines, one get a safe write pattern: // Decode: [ 0..15][16..31][32..47][ 0..15][16..31][32..47][0.. // Deblock: [ 0..11][12..27][28..43][-4..11][12..27][28... // Note that multi-threaded output _without_ deblocking can make use of two // cache lines of 16 pixels only, since there's no lagging behind. The decoding // and output process have non-concurrent writing: // Decode: [ 0..15][16..31][ 0..15][16..31][... // io->put: [ 0..15][16..31][ 0..15][... #define MT_CACHE_LINES 3 #define ST_CACHE_LINES 1 // 1 cache row only for single-threaded case // Initialize multi/single-thread worker static int InitThreadContext(VP8Decoder* const dec) { dec->cache_id_ = 0; if (dec->mt_method_ > 0) { WebPWorker* const worker = &dec->worker_; if (!WebPWorkerReset(worker)) { return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY, "thread initialization failed."); } worker->data1 = dec; worker->data2 = (void*)&dec->thread_ctx_.io_; worker->hook = (WebPWorkerHook)FinishRow; dec->num_caches_ = (dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1; } else { dec->num_caches_ = ST_CACHE_LINES; } return 1; } int VP8GetThreadMethod(const WebPDecoderOptions* const options, const WebPHeaderStructure* const headers, int width, int height) { if (options == NULL || options->use_threads == 0) { return 0; } (void)headers; (void)width; (void)height; assert(!headers->is_lossless); #if defined(WEBP_USE_THREAD) if (width < MIN_WIDTH_FOR_THREADS) return 0; // TODO(skal): tune the heuristic further #if 0 if (height < 2 * width) return 2; #endif return 2; #else // !WEBP_USE_THREAD return 0; #endif } #undef MT_CACHE_LINES #undef ST_CACHE_LINES //------------------------------------------------------------------------------ // Memory setup static int AllocateMemory(VP8Decoder* const dec) { const int num_caches = dec->num_caches_; const int mb_w = dec->mb_w_; // Note: we use 'size_t' when there's no overflow risk, uint64_t otherwise. const size_t intra_pred_mode_size = 4 * mb_w * sizeof(uint8_t); const size_t top_size = sizeof(VP8TopSamples) * mb_w; const size_t mb_info_size = (mb_w + 1) * sizeof(VP8MB); const size_t f_info_size = (dec->filter_type_ > 0) ? mb_w * (dec->mt_method_ > 0 ? 2 : 1) * sizeof(VP8FInfo) : 0; const size_t yuv_size = YUV_SIZE * sizeof(*dec->yuv_b_); const size_t mb_data_size = (dec->mt_method_ == 2 ? 2 : 1) * mb_w * sizeof(*dec->mb_data_); const size_t cache_height = (16 * num_caches + kFilterExtraRows[dec->filter_type_]) * 3 / 2; const size_t cache_size = top_size * cache_height; // alpha_size is the only one that scales as width x height. const uint64_t alpha_size = (dec->alpha_data_ != NULL) ? (uint64_t)dec->pic_hdr_.width_ * dec->pic_hdr_.height_ : 0ULL; const uint64_t needed = (uint64_t)intra_pred_mode_size + top_size + mb_info_size + f_info_size + yuv_size + mb_data_size + cache_size + alpha_size + ALIGN_MASK; uint8_t* mem; if (needed != (size_t)needed) return 0; // check for overflow if (needed > dec->mem_size_) { free(dec->mem_); dec->mem_size_ = 0; dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t)); if (dec->mem_ == NULL) { return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY, "no memory during frame initialization."); } // down-cast is ok, thanks to WebPSafeAlloc() above. dec->mem_size_ = (size_t)needed; } mem = (uint8_t*)dec->mem_; dec->intra_t_ = (uint8_t*)mem; mem += intra_pred_mode_size; dec->yuv_t_ = (VP8TopSamples*)mem; mem += top_size; dec->mb_info_ = ((VP8MB*)mem) + 1; mem += mb_info_size; dec->f_info_ = f_info_size ? (VP8FInfo*)mem : NULL; mem += f_info_size; dec->thread_ctx_.id_ = 0; dec->thread_ctx_.f_info_ = dec->f_info_; if (dec->mt_method_ > 0) { // secondary cache line. The deblocking process need to make use of the // filtering strength from previous macroblock row, while the new ones // are being decoded in parallel. We'll just swap the pointers. dec->thread_ctx_.f_info_ += mb_w; } mem = (uint8_t*)((uintptr_t)(mem + ALIGN_MASK) & ~ALIGN_MASK); assert((yuv_size & ALIGN_MASK) == 0); dec->yuv_b_ = (uint8_t*)mem; mem += yuv_size; dec->mb_data_ = (VP8MBData*)mem; dec->thread_ctx_.mb_data_ = (VP8MBData*)mem; if (dec->mt_method_ == 2) { dec->thread_ctx_.mb_data_ += mb_w; } mem += mb_data_size; dec->cache_y_stride_ = 16 * mb_w; dec->cache_uv_stride_ = 8 * mb_w; { const int extra_rows = kFilterExtraRows[dec->filter_type_]; const int extra_y = extra_rows * dec->cache_y_stride_; const int extra_uv = (extra_rows / 2) * dec->cache_uv_stride_; dec->cache_y_ = ((uint8_t*)mem) + extra_y; dec->cache_u_ = dec->cache_y_ + 16 * num_caches * dec->cache_y_stride_ + extra_uv; dec->cache_v_ = dec->cache_u_ + 8 * num_caches * dec->cache_uv_stride_ + extra_uv; dec->cache_id_ = 0; } mem += cache_size; // alpha plane dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL; mem += alpha_size; assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_); // note: left/top-info is initialized once for all. memset(dec->mb_info_ - 1, 0, mb_info_size); VP8InitScanline(dec); // initialize left too. // initialize top memset(dec->intra_t_, B_DC_PRED, intra_pred_mode_size); return 1; } static void InitIo(VP8Decoder* const dec, VP8Io* io) { // prepare 'io' io->mb_y = 0; io->y = dec->cache_y_; io->u = dec->cache_u_; io->v = dec->cache_v_; io->y_stride = dec->cache_y_stride_; io->uv_stride = dec->cache_uv_stride_; io->a = NULL; } int VP8InitFrame(VP8Decoder* const dec, VP8Io* io) { if (!InitThreadContext(dec)) return 0; // call first. Sets dec->num_caches_. if (!AllocateMemory(dec)) return 0; InitIo(dec, io); VP8DspInit(); // Init critical function pointers and look-up tables. return 1; } //------------------------------------------------------------------------------ // Main reconstruction function. static const int kScan[16] = { 0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS, 0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * BPS, 0 + 8 * BPS, 4 + 8 * BPS, 8 + 8 * BPS, 12 + 8 * BPS, 0 + 12 * BPS, 4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS }; static int CheckMode(int mb_x, int mb_y, int mode) { if (mode == B_DC_PRED) { if (mb_x == 0) { return (mb_y == 0) ? B_DC_PRED_NOTOPLEFT : B_DC_PRED_NOLEFT; } else { return (mb_y == 0) ? B_DC_PRED_NOTOP : B_DC_PRED; } } return mode; } static void Copy32b(uint8_t* dst, uint8_t* src) { memcpy(dst, src, 4); } static WEBP_INLINE void DoTransform(uint32_t bits, const int16_t* const src, uint8_t* const dst) { switch (bits >> 30) { case 3: VP8Transform(src, dst, 0); break; case 2: VP8TransformAC3(src, dst); break; case 1: VP8TransformDC(src, dst); break; default: break; } } static void DoUVTransform(uint32_t bits, const int16_t* const src, uint8_t* const dst) { if (bits & 0xff) { // any non-zero coeff at all? if (bits & 0xaa) { // any non-zero AC coefficient? VP8TransformUV(src, dst); // note we don't use the AC3 variant for U/V } else { VP8TransformDCUV(src, dst); } } } static void ReconstructRow(const VP8Decoder* const dec, const VP8ThreadContext* ctx) { int j; int mb_x; const int mb_y = ctx->mb_y_; const int cache_id = ctx->id_; uint8_t* const y_dst = dec->yuv_b_ + Y_OFF; uint8_t* const u_dst = dec->yuv_b_ + U_OFF; uint8_t* const v_dst = dec->yuv_b_ + V_OFF; for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) { const VP8MBData* const block = ctx->mb_data_ + mb_x; // Rotate in the left samples from previously decoded block. We move four // pixels at a time for alignment reason, and because of in-loop filter. if (mb_x > 0) { for (j = -1; j < 16; ++j) { Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]); } for (j = -1; j < 8; ++j) { Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]); Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]); } } else { for (j = 0; j < 16; ++j) { y_dst[j * BPS - 1] = 129; } for (j = 0; j < 8; ++j) { u_dst[j * BPS - 1] = 129; v_dst[j * BPS - 1] = 129; } // Init top-left sample on left column too if (mb_y > 0) { y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129; } } { // bring top samples into the cache VP8TopSamples* const top_yuv = dec->yuv_t_ + mb_x; const int16_t* const coeffs = block->coeffs_; uint32_t bits = block->non_zero_y_; int n; if (mb_y > 0) { memcpy(y_dst - BPS, top_yuv[0].y, 16); memcpy(u_dst - BPS, top_yuv[0].u, 8); memcpy(v_dst - BPS, top_yuv[0].v, 8); } else if (mb_x == 0) { // we only need to do this init once at block (0,0). // Afterward, it remains valid for the whole topmost row. memset(y_dst - BPS - 1, 127, 16 + 4 + 1); memset(u_dst - BPS - 1, 127, 8 + 1); memset(v_dst - BPS - 1, 127, 8 + 1); } // predict and add residuals if (block->is_i4x4_) { // 4x4 uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16); if (mb_y > 0) { if (mb_x >= dec->mb_w_ - 1) { // on rightmost border memset(top_right, top_yuv[0].y[15], sizeof(*top_right)); } else { memcpy(top_right, top_yuv[1].y, sizeof(*top_right)); } } // replicate the top-right pixels below top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0]; // predict and add residuals for all 4x4 blocks in turn. for (n = 0; n < 16; ++n, bits <<= 2) { uint8_t* const dst = y_dst + kScan[n]; VP8PredLuma4[block->imodes_[n]](dst); DoTransform(bits, coeffs + n * 16, dst); } } else { // 16x16 const int pred_func = CheckMode(mb_x, mb_y, block->imodes_[0]); VP8PredLuma16[pred_func](y_dst); if (bits != 0) { for (n = 0; n < 16; ++n, bits <<= 2) { DoTransform(bits, coeffs + n * 16, y_dst + kScan[n]); } } } { // Chroma const uint32_t bits_uv = block->non_zero_uv_; const int pred_func = CheckMode(mb_x, mb_y, block->uvmode_); VP8PredChroma8[pred_func](u_dst); VP8PredChroma8[pred_func](v_dst); DoUVTransform(bits_uv >> 0, coeffs + 16 * 16, u_dst); DoUVTransform(bits_uv >> 8, coeffs + 20 * 16, v_dst); } // stash away top samples for next block if (mb_y < dec->mb_h_ - 1) { memcpy(top_yuv[0].y, y_dst + 15 * BPS, 16); memcpy(top_yuv[0].u, u_dst + 7 * BPS, 8); memcpy(top_yuv[0].v, v_dst + 7 * BPS, 8); } } // Transfer reconstructed samples from yuv_b_ cache to final destination. { const int y_offset = cache_id * 16 * dec->cache_y_stride_; const int uv_offset = cache_id * 8 * dec->cache_uv_stride_; uint8_t* const y_out = dec->cache_y_ + mb_x * 16 + y_offset; uint8_t* const u_out = dec->cache_u_ + mb_x * 8 + uv_offset; uint8_t* const v_out = dec->cache_v_ + mb_x * 8 + uv_offset; for (j = 0; j < 16; ++j) { memcpy(y_out + j * dec->cache_y_stride_, y_dst + j * BPS, 16); } for (j = 0; j < 8; ++j) { memcpy(u_out + j * dec->cache_uv_stride_, u_dst + j * BPS, 8); memcpy(v_out + j * dec->cache_uv_stride_, v_dst + j * BPS, 8); } } } } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/alphai.h0000644000014400001440000000310412255002107012770 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Alpha decoder: internal header. // // Author: Urvang (urvang@google.com) #ifndef WEBP_DEC_ALPHAI_H_ #define WEBP_DEC_ALPHAI_H_ #include "./webpi.h" #include "../utils/filters.h" #ifdef __cplusplus extern "C" { #endif struct VP8LDecoder; // Defined in dec/vp8li.h. typedef struct ALPHDecoder ALPHDecoder; struct ALPHDecoder { int width_; int height_; int method_; WEBP_FILTER_TYPE filter_; int pre_processing_; struct VP8LDecoder* vp8l_dec_; VP8Io io_; int use_8b_decode; // Although alpha channel requires only 1 byte per // pixel, sometimes VP8LDecoder may need to allocate // 4 bytes per pixel internally during decode. }; //------------------------------------------------------------------------------ // internal functions. Not public. // Allocates a new alpha decoder instance. ALPHDecoder* ALPHNew(void); // Clears and deallocates an alpha decoder instance. void ALPHDelete(ALPHDecoder* const dec); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_DEC_ALPHAI_H_ */ libwebp-0.4.0/src/dec/idec.c0000644000014400001440000006677612255002107012461 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Incremental decoding // // Author: somnath@google.com (Somnath Banerjee) #include #include #include #include "./alphai.h" #include "./webpi.h" #include "./vp8i.h" #include "../utils/utils.h" // In append mode, buffer allocations increase as multiples of this value. // Needs to be a power of 2. #define CHUNK_SIZE 4096 #define MAX_MB_SIZE 4096 //------------------------------------------------------------------------------ // Data structures for memory and states // Decoding states. State normally flows as: // WEBP_HEADER->VP8_HEADER->VP8_PARTS0->VP8_DATA->DONE for a lossy image, and // WEBP_HEADER->VP8L_HEADER->VP8L_DATA->DONE for a lossless image. // If there is any error the decoder goes into state ERROR. typedef enum { STATE_WEBP_HEADER, // All the data before that of the VP8/VP8L chunk. STATE_VP8_HEADER, // The VP8 Frame header (within the VP8 chunk). STATE_VP8_PARTS0, STATE_VP8_DATA, STATE_VP8L_HEADER, STATE_VP8L_DATA, STATE_DONE, STATE_ERROR } DecState; // Operating state for the MemBuffer typedef enum { MEM_MODE_NONE = 0, MEM_MODE_APPEND, MEM_MODE_MAP } MemBufferMode; // storage for partition #0 and partial data (in a rolling fashion) typedef struct { MemBufferMode mode_; // Operation mode size_t start_; // start location of the data to be decoded size_t end_; // end location size_t buf_size_; // size of the allocated buffer uint8_t* buf_; // We don't own this buffer in case WebPIUpdate() size_t part0_size_; // size of partition #0 const uint8_t* part0_buf_; // buffer to store partition #0 } MemBuffer; struct WebPIDecoder { DecState state_; // current decoding state WebPDecParams params_; // Params to store output info int is_lossless_; // for down-casting 'dec_'. void* dec_; // either a VP8Decoder or a VP8LDecoder instance VP8Io io_; MemBuffer mem_; // input memory buffer. WebPDecBuffer output_; // output buffer (when no external one is supplied) size_t chunk_size_; // Compressed VP8/VP8L size extracted from Header. }; // MB context to restore in case VP8DecodeMB() fails typedef struct { VP8MB left_; VP8MB info_; uint8_t intra_t_[4]; uint8_t intra_l_[4]; VP8BitReader br_; VP8BitReader token_br_; } MBContext; //------------------------------------------------------------------------------ // MemBuffer: incoming data handling static void RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) { if (br->buf_ != NULL) { br->buf_ += offset; br->buf_end_ += offset; } } static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) { return (mem->end_ - mem->start_); } // Check if we need to preserve the compressed alpha data, as it may not have // been decoded yet. static int NeedCompressedAlpha(const WebPIDecoder* const idec) { if (idec->state_ == STATE_WEBP_HEADER) { // We haven't parsed the headers yet, so we don't know whether the image is // lossy or lossless. This also means that we haven't parsed the ALPH chunk. return 0; } if (idec->is_lossless_) { return 0; // ALPH chunk is not present for lossless images. } else { const VP8Decoder* const dec = (VP8Decoder*)idec->dec_; assert(dec != NULL); // Must be true as idec->state_ != STATE_WEBP_HEADER. return (dec->alpha_data_ != NULL) && !dec->is_alpha_decoded_; } } static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) { MemBuffer* const mem = &idec->mem_; const uint8_t* const new_base = mem->buf_ + mem->start_; // note: for VP8, setting up idec->io_ is only really needed at the beginning // of the decoding, till partition #0 is complete. idec->io_.data = new_base; idec->io_.data_size = MemDataSize(mem); if (idec->dec_ != NULL) { if (!idec->is_lossless_) { VP8Decoder* const dec = (VP8Decoder*)idec->dec_; const int last_part = dec->num_parts_ - 1; if (offset != 0) { int p; for (p = 0; p <= last_part; ++p) { RemapBitReader(dec->parts_ + p, offset); } // Remap partition #0 data pointer to new offset, but only in MAP // mode (in APPEND mode, partition #0 is copied into a fixed memory). if (mem->mode_ == MEM_MODE_MAP) { RemapBitReader(&dec->br_, offset); } } assert(last_part >= 0); dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_; if (NeedCompressedAlpha(idec)) { ALPHDecoder* const alph_dec = dec->alph_dec_; dec->alpha_data_ += offset; if (alph_dec != NULL) { if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) { VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_; assert(alph_vp8l_dec != NULL); assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN); VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_, dec->alpha_data_ + ALPHA_HEADER_LEN, dec->alpha_data_size_ - ALPHA_HEADER_LEN); } else { // alph_dec->method_ == ALPHA_NO_COMPRESSION // Nothing special to do in this case. } } } } else { // Resize lossless bitreader VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_; VP8LBitReaderSetBuffer(&dec->br_, new_base, MemDataSize(mem)); } } } // Appends data to the end of MemBuffer->buf_. It expands the allocated memory // size if required and also updates VP8BitReader's if new memory is allocated. static int AppendToMemBuffer(WebPIDecoder* const idec, const uint8_t* const data, size_t data_size) { VP8Decoder* const dec = (VP8Decoder*)idec->dec_; MemBuffer* const mem = &idec->mem_; const int need_compressed_alpha = NeedCompressedAlpha(idec); const uint8_t* const old_start = mem->buf_ + mem->start_; const uint8_t* const old_base = need_compressed_alpha ? dec->alpha_data_ : old_start; assert(mem->mode_ == MEM_MODE_APPEND); if (data_size > MAX_CHUNK_PAYLOAD) { // security safeguard: trying to allocate more than what the format // allows for a chunk should be considered a smoke smell. return 0; } if (mem->end_ + data_size > mem->buf_size_) { // Need some free memory const size_t new_mem_start = old_start - old_base; const size_t current_size = MemDataSize(mem) + new_mem_start; const uint64_t new_size = (uint64_t)current_size + data_size; const uint64_t extra_size = (new_size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1); uint8_t* const new_buf = (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf)); if (new_buf == NULL) return 0; memcpy(new_buf, old_base, current_size); free(mem->buf_); mem->buf_ = new_buf; mem->buf_size_ = (size_t)extra_size; mem->start_ = new_mem_start; mem->end_ = current_size; } memcpy(mem->buf_ + mem->end_, data, data_size); mem->end_ += data_size; assert(mem->end_ <= mem->buf_size_); DoRemap(idec, mem->buf_ + mem->start_ - old_start); return 1; } static int RemapMemBuffer(WebPIDecoder* const idec, const uint8_t* const data, size_t data_size) { MemBuffer* const mem = &idec->mem_; const uint8_t* const old_buf = mem->buf_; const uint8_t* const old_start = old_buf + mem->start_; assert(mem->mode_ == MEM_MODE_MAP); if (data_size < mem->buf_size_) return 0; // can't remap to a shorter buffer! mem->buf_ = (uint8_t*)data; mem->end_ = mem->buf_size_ = data_size; DoRemap(idec, mem->buf_ + mem->start_ - old_start); return 1; } static void InitMemBuffer(MemBuffer* const mem) { mem->mode_ = MEM_MODE_NONE; mem->buf_ = NULL; mem->buf_size_ = 0; mem->part0_buf_ = NULL; mem->part0_size_ = 0; } static void ClearMemBuffer(MemBuffer* const mem) { assert(mem); if (mem->mode_ == MEM_MODE_APPEND) { free(mem->buf_); free((void*)mem->part0_buf_); } } static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) { if (mem->mode_ == MEM_MODE_NONE) { mem->mode_ = expected; // switch to the expected mode } else if (mem->mode_ != expected) { return 0; // we mixed the modes => error } assert(mem->mode_ == expected); // mode is ok return 1; } //------------------------------------------------------------------------------ // Macroblock-decoding contexts static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br, MBContext* const context) { const VP8BitReader* const br = &dec->br_; const VP8MB* const left = dec->mb_info_ - 1; const VP8MB* const info = dec->mb_info_ + dec->mb_x_; context->left_ = *left; context->info_ = *info; context->br_ = *br; context->token_br_ = *token_br; memcpy(context->intra_t_, dec->intra_t_ + 4 * dec->mb_x_, 4); memcpy(context->intra_l_, dec->intra_l_, 4); } static void RestoreContext(const MBContext* context, VP8Decoder* const dec, VP8BitReader* const token_br) { VP8BitReader* const br = &dec->br_; VP8MB* const left = dec->mb_info_ - 1; VP8MB* const info = dec->mb_info_ + dec->mb_x_; *left = context->left_; *info = context->info_; *br = context->br_; *token_br = context->token_br_; memcpy(dec->intra_t_ + 4 * dec->mb_x_, context->intra_t_, 4); memcpy(dec->intra_l_, context->intra_l_, 4); } //------------------------------------------------------------------------------ static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) { if (idec->state_ == STATE_VP8_DATA) { VP8Io* const io = &idec->io_; if (io->teardown != NULL) { io->teardown(io); } } idec->state_ = STATE_ERROR; return error; } static void ChangeState(WebPIDecoder* const idec, DecState new_state, size_t consumed_bytes) { MemBuffer* const mem = &idec->mem_; idec->state_ = new_state; mem->start_ += consumed_bytes; assert(mem->start_ <= mem->end_); idec->io_.data = mem->buf_ + mem->start_; idec->io_.data_size = MemDataSize(mem); } // Headers static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) { MemBuffer* const mem = &idec->mem_; const uint8_t* data = mem->buf_ + mem->start_; size_t curr_size = MemDataSize(mem); VP8StatusCode status; WebPHeaderStructure headers; headers.data = data; headers.data_size = curr_size; status = WebPParseHeaders(&headers); if (status == VP8_STATUS_NOT_ENOUGH_DATA) { return VP8_STATUS_SUSPENDED; // We haven't found a VP8 chunk yet. } else if (status != VP8_STATUS_OK) { return IDecError(idec, status); } idec->chunk_size_ = headers.compressed_size; idec->is_lossless_ = headers.is_lossless; if (!idec->is_lossless_) { VP8Decoder* const dec = VP8New(); if (dec == NULL) { return VP8_STATUS_OUT_OF_MEMORY; } idec->dec_ = dec; dec->alpha_data_ = headers.alpha_data; dec->alpha_data_size_ = headers.alpha_data_size; ChangeState(idec, STATE_VP8_HEADER, headers.offset); } else { VP8LDecoder* const dec = VP8LNew(); if (dec == NULL) { return VP8_STATUS_OUT_OF_MEMORY; } idec->dec_ = dec; ChangeState(idec, STATE_VP8L_HEADER, headers.offset); } return VP8_STATUS_OK; } static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) { const uint8_t* data = idec->mem_.buf_ + idec->mem_.start_; const size_t curr_size = MemDataSize(&idec->mem_); int width, height; uint32_t bits; if (curr_size < VP8_FRAME_HEADER_SIZE) { // Not enough data bytes to extract VP8 Frame Header. return VP8_STATUS_SUSPENDED; } if (!VP8GetInfo(data, curr_size, idec->chunk_size_, &width, &height)) { return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR); } bits = data[0] | (data[1] << 8) | (data[2] << 16); idec->mem_.part0_size_ = (bits >> 5) + VP8_FRAME_HEADER_SIZE; idec->io_.data = data; idec->io_.data_size = curr_size; idec->state_ = STATE_VP8_PARTS0; return VP8_STATUS_OK; } // Partition #0 static int CopyParts0Data(WebPIDecoder* const idec) { VP8Decoder* const dec = (VP8Decoder*)idec->dec_; VP8BitReader* const br = &dec->br_; const size_t psize = br->buf_end_ - br->buf_; MemBuffer* const mem = &idec->mem_; assert(!idec->is_lossless_); assert(mem->part0_buf_ == NULL); assert(psize > 0); assert(psize <= mem->part0_size_); // Format limit: no need for runtime check if (mem->mode_ == MEM_MODE_APPEND) { // We copy and grab ownership of the partition #0 data. uint8_t* const part0_buf = (uint8_t*)malloc(psize); if (part0_buf == NULL) { return 0; } memcpy(part0_buf, br->buf_, psize); mem->part0_buf_ = part0_buf; br->buf_ = part0_buf; br->buf_end_ = part0_buf + psize; } else { // Else: just keep pointers to the partition #0's data in dec_->br_. } mem->start_ += psize; return 1; } static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) { VP8Decoder* const dec = (VP8Decoder*)idec->dec_; VP8Io* const io = &idec->io_; const WebPDecParams* const params = &idec->params_; WebPDecBuffer* const output = params->output; // Wait till we have enough data for the whole partition #0 if (MemDataSize(&idec->mem_) < idec->mem_.part0_size_) { return VP8_STATUS_SUSPENDED; } if (!VP8GetHeaders(dec, io)) { const VP8StatusCode status = dec->status_; if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) { // treating NOT_ENOUGH_DATA as SUSPENDED state return VP8_STATUS_SUSPENDED; } return IDecError(idec, status); } // Allocate/Verify output buffer now dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options, output); if (dec->status_ != VP8_STATUS_OK) { return IDecError(idec, dec->status_); } // This change must be done before calling VP8InitFrame() dec->mt_method_ = VP8GetThreadMethod(params->options, NULL, io->width, io->height); VP8InitDithering(params->options, dec); if (!CopyParts0Data(idec)) { return IDecError(idec, VP8_STATUS_OUT_OF_MEMORY); } // Finish setting up the decoding parameters. Will call io->setup(). if (VP8EnterCritical(dec, io) != VP8_STATUS_OK) { return IDecError(idec, dec->status_); } // Note: past this point, teardown() must always be called // in case of error. idec->state_ = STATE_VP8_DATA; // Allocate memory and prepare everything. if (!VP8InitFrame(dec, io)) { return IDecError(idec, dec->status_); } return VP8_STATUS_OK; } // Remaining partitions static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) { VP8Decoder* const dec = (VP8Decoder*)idec->dec_; VP8Io* const io = &idec->io_; assert(dec->ready_); for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) { VP8BitReader* token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) { MBContext context; SaveContext(dec, token_br, &context); if (!VP8DecodeMB(dec, token_br)) { RestoreContext(&context, dec, token_br); // We shouldn't fail when MAX_MB data was available if (dec->num_parts_ == 1 && MemDataSize(&idec->mem_) > MAX_MB_SIZE) { return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR); } return VP8_STATUS_SUSPENDED; } // Release buffer only if there is only one partition if (dec->num_parts_ == 1) { idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_; assert(idec->mem_.start_ <= idec->mem_.end_); } } VP8InitScanline(dec); // Prepare for next scanline // Reconstruct, filter and emit the row. if (!VP8ProcessRow(dec, io)) { return IDecError(idec, VP8_STATUS_USER_ABORT); } } // Synchronize the thread and check for errors. if (!VP8ExitCritical(dec, io)) { return IDecError(idec, VP8_STATUS_USER_ABORT); } dec->ready_ = 0; idec->state_ = STATE_DONE; return VP8_STATUS_OK; } static VP8StatusCode ErrorStatusLossless(WebPIDecoder* const idec, VP8StatusCode status) { if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) { return VP8_STATUS_SUSPENDED; } return IDecError(idec, status); } static VP8StatusCode DecodeVP8LHeader(WebPIDecoder* const idec) { VP8Io* const io = &idec->io_; VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_; const WebPDecParams* const params = &idec->params_; WebPDecBuffer* const output = params->output; size_t curr_size = MemDataSize(&idec->mem_); assert(idec->is_lossless_); // Wait until there's enough data for decoding header. if (curr_size < (idec->chunk_size_ >> 3)) { return VP8_STATUS_SUSPENDED; } if (!VP8LDecodeHeader(dec, io)) { return ErrorStatusLossless(idec, dec->status_); } // Allocate/verify output buffer now. dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options, output); if (dec->status_ != VP8_STATUS_OK) { return IDecError(idec, dec->status_); } idec->state_ = STATE_VP8L_DATA; return VP8_STATUS_OK; } static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) { VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_; const size_t curr_size = MemDataSize(&idec->mem_); assert(idec->is_lossless_); // At present Lossless decoder can't decode image incrementally. So wait till // all the image data is aggregated before image can be decoded. if (curr_size < idec->chunk_size_) { return VP8_STATUS_SUSPENDED; } if (!VP8LDecodeImage(dec)) { return ErrorStatusLossless(idec, dec->status_); } idec->state_ = STATE_DONE; return VP8_STATUS_OK; } // Main decoding loop static VP8StatusCode IDecode(WebPIDecoder* idec) { VP8StatusCode status = VP8_STATUS_SUSPENDED; if (idec->state_ == STATE_WEBP_HEADER) { status = DecodeWebPHeaders(idec); } else { if (idec->dec_ == NULL) { return VP8_STATUS_SUSPENDED; // can't continue if we have no decoder. } } if (idec->state_ == STATE_VP8_HEADER) { status = DecodeVP8FrameHeader(idec); } if (idec->state_ == STATE_VP8_PARTS0) { status = DecodePartition0(idec); } if (idec->state_ == STATE_VP8_DATA) { status = DecodeRemaining(idec); } if (idec->state_ == STATE_VP8L_HEADER) { status = DecodeVP8LHeader(idec); } if (idec->state_ == STATE_VP8L_DATA) { status = DecodeVP8LData(idec); } return status; } //------------------------------------------------------------------------------ // Public functions WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) { WebPIDecoder* idec = (WebPIDecoder*)calloc(1, sizeof(*idec)); if (idec == NULL) { return NULL; } idec->state_ = STATE_WEBP_HEADER; idec->chunk_size_ = 0; InitMemBuffer(&idec->mem_); WebPInitDecBuffer(&idec->output_); VP8InitIo(&idec->io_); WebPResetDecParams(&idec->params_); idec->params_.output = (output_buffer != NULL) ? output_buffer : &idec->output_; WebPInitCustomIo(&idec->params_, &idec->io_); // Plug the I/O functions. return idec; } WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size, WebPDecoderConfig* config) { WebPIDecoder* idec; // Parse the bitstream's features, if requested: if (data != NULL && data_size > 0 && config != NULL) { if (WebPGetFeatures(data, data_size, &config->input) != VP8_STATUS_OK) { return NULL; } } // Create an instance of the incremental decoder idec = WebPINewDecoder(config ? &config->output : NULL); if (idec == NULL) { return NULL; } // Finish initialization if (config != NULL) { idec->params_.options = &config->options; } return idec; } void WebPIDelete(WebPIDecoder* idec) { if (idec == NULL) return; if (idec->dec_ != NULL) { if (!idec->is_lossless_) { if (idec->state_ == STATE_VP8_DATA) { // Synchronize the thread, clean-up and check for errors. VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_); } VP8Delete((VP8Decoder*)idec->dec_); } else { VP8LDelete((VP8LDecoder*)idec->dec_); } } ClearMemBuffer(&idec->mem_); WebPFreeDecBuffer(&idec->output_); free(idec); } //------------------------------------------------------------------------------ // Wrapper toward WebPINewDecoder WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer, size_t output_buffer_size, int output_stride) { const int is_external_memory = (output_buffer != NULL); WebPIDecoder* idec; if (mode >= MODE_YUV) return NULL; if (!is_external_memory) { // Overwrite parameters to sane values. output_buffer_size = 0; output_stride = 0; } else { // A buffer was passed. Validate the other params. if (output_stride == 0 || output_buffer_size == 0) { return NULL; // invalid parameter. } } idec = WebPINewDecoder(NULL); if (idec == NULL) return NULL; idec->output_.colorspace = mode; idec->output_.is_external_memory = is_external_memory; idec->output_.u.RGBA.rgba = output_buffer; idec->output_.u.RGBA.stride = output_stride; idec->output_.u.RGBA.size = output_buffer_size; return idec; } WebPIDecoder* WebPINewYUVA(uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride, uint8_t* a, size_t a_size, int a_stride) { const int is_external_memory = (luma != NULL); WebPIDecoder* idec; WEBP_CSP_MODE colorspace; if (!is_external_memory) { // Overwrite parameters to sane values. luma_size = u_size = v_size = a_size = 0; luma_stride = u_stride = v_stride = a_stride = 0; u = v = a = NULL; colorspace = MODE_YUVA; } else { // A luma buffer was passed. Validate the other parameters. if (u == NULL || v == NULL) return NULL; if (luma_size == 0 || u_size == 0 || v_size == 0) return NULL; if (luma_stride == 0 || u_stride == 0 || v_stride == 0) return NULL; if (a != NULL) { if (a_size == 0 || a_stride == 0) return NULL; } colorspace = (a == NULL) ? MODE_YUV : MODE_YUVA; } idec = WebPINewDecoder(NULL); if (idec == NULL) return NULL; idec->output_.colorspace = colorspace; idec->output_.is_external_memory = is_external_memory; idec->output_.u.YUVA.y = luma; idec->output_.u.YUVA.y_stride = luma_stride; idec->output_.u.YUVA.y_size = luma_size; idec->output_.u.YUVA.u = u; idec->output_.u.YUVA.u_stride = u_stride; idec->output_.u.YUVA.u_size = u_size; idec->output_.u.YUVA.v = v; idec->output_.u.YUVA.v_stride = v_stride; idec->output_.u.YUVA.v_size = v_size; idec->output_.u.YUVA.a = a; idec->output_.u.YUVA.a_stride = a_stride; idec->output_.u.YUVA.a_size = a_size; return idec; } WebPIDecoder* WebPINewYUV(uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride) { return WebPINewYUVA(luma, luma_size, luma_stride, u, u_size, u_stride, v, v_size, v_stride, NULL, 0, 0); } //------------------------------------------------------------------------------ static VP8StatusCode IDecCheckStatus(const WebPIDecoder* const idec) { assert(idec); if (idec->state_ == STATE_ERROR) { return VP8_STATUS_BITSTREAM_ERROR; } if (idec->state_ == STATE_DONE) { return VP8_STATUS_OK; } return VP8_STATUS_SUSPENDED; } VP8StatusCode WebPIAppend(WebPIDecoder* idec, const uint8_t* data, size_t data_size) { VP8StatusCode status; if (idec == NULL || data == NULL) { return VP8_STATUS_INVALID_PARAM; } status = IDecCheckStatus(idec); if (status != VP8_STATUS_SUSPENDED) { return status; } // Check mixed calls between RemapMemBuffer and AppendToMemBuffer. if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_APPEND)) { return VP8_STATUS_INVALID_PARAM; } // Append data to memory buffer if (!AppendToMemBuffer(idec, data, data_size)) { return VP8_STATUS_OUT_OF_MEMORY; } return IDecode(idec); } VP8StatusCode WebPIUpdate(WebPIDecoder* idec, const uint8_t* data, size_t data_size) { VP8StatusCode status; if (idec == NULL || data == NULL) { return VP8_STATUS_INVALID_PARAM; } status = IDecCheckStatus(idec); if (status != VP8_STATUS_SUSPENDED) { return status; } // Check mixed calls between RemapMemBuffer and AppendToMemBuffer. if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_MAP)) { return VP8_STATUS_INVALID_PARAM; } // Make the memory buffer point to the new buffer if (!RemapMemBuffer(idec, data, data_size)) { return VP8_STATUS_INVALID_PARAM; } return IDecode(idec); } //------------------------------------------------------------------------------ static const WebPDecBuffer* GetOutputBuffer(const WebPIDecoder* const idec) { if (idec == NULL || idec->dec_ == NULL) { return NULL; } if (idec->state_ <= STATE_VP8_PARTS0) { return NULL; } return idec->params_.output; } const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec, int* left, int* top, int* width, int* height) { const WebPDecBuffer* const src = GetOutputBuffer(idec); if (left != NULL) *left = 0; if (top != NULL) *top = 0; // TODO(skal): later include handling of rotations. if (src) { if (width != NULL) *width = src->width; if (height != NULL) *height = idec->params_.last_y; } else { if (width != NULL) *width = 0; if (height != NULL) *height = 0; } return src; } uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y, int* width, int* height, int* stride) { const WebPDecBuffer* const src = GetOutputBuffer(idec); if (src == NULL) return NULL; if (src->colorspace >= MODE_YUV) { return NULL; } if (last_y != NULL) *last_y = idec->params_.last_y; if (width != NULL) *width = src->width; if (height != NULL) *height = src->height; if (stride != NULL) *stride = src->u.RGBA.stride; return src->u.RGBA.rgba; } uint8_t* WebPIDecGetYUVA(const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, uint8_t** a, int* width, int* height, int* stride, int* uv_stride, int* a_stride) { const WebPDecBuffer* const src = GetOutputBuffer(idec); if (src == NULL) return NULL; if (src->colorspace < MODE_YUV) { return NULL; } if (last_y != NULL) *last_y = idec->params_.last_y; if (u != NULL) *u = src->u.YUVA.u; if (v != NULL) *v = src->u.YUVA.v; if (a != NULL) *a = src->u.YUVA.a; if (width != NULL) *width = src->width; if (height != NULL) *height = src->height; if (stride != NULL) *stride = src->u.YUVA.y_stride; if (uv_stride != NULL) *uv_stride = src->u.YUVA.u_stride; if (a_stride != NULL) *a_stride = src->u.YUVA.a_stride; return src->u.YUVA.y; } int WebPISetIOHooks(WebPIDecoder* const idec, VP8IoPutHook put, VP8IoSetupHook setup, VP8IoTeardownHook teardown, void* user_data) { if (idec == NULL || idec->state_ > STATE_WEBP_HEADER) { return 0; } idec->io_.put = put; idec->io_.setup = setup; idec->io_.teardown = teardown; idec->io_.opaque = user_data; return 1; } libwebp-0.4.0/src/dec/vp8l.c0000644000014400001440000013411012255002107012420 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // main entry for the decoder // // Authors: Vikas Arora (vikaas.arora@gmail.com) // Jyrki Alakuijala (jyrki@google.com) #include #include #include "./alphai.h" #include "./vp8li.h" #include "../dsp/lossless.h" #include "../dsp/yuv.h" #include "../utils/alpha_processing.h" #include "../utils/huffman.h" #include "../utils/utils.h" #define NUM_ARGB_CACHE_ROWS 16 static const int kCodeLengthLiterals = 16; static const int kCodeLengthRepeatCode = 16; static const int kCodeLengthExtraBits[3] = { 2, 3, 7 }; static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 }; // ----------------------------------------------------------------------------- // Five Huffman codes are used at each meta code: // 1. green + length prefix codes + color cache codes, // 2. alpha, // 3. red, // 4. blue, and, // 5. distance prefix codes. typedef enum { GREEN = 0, RED = 1, BLUE = 2, ALPHA = 3, DIST = 4 } HuffIndex; static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = { NUM_LITERAL_CODES + NUM_LENGTH_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_DISTANCE_CODES }; #define NUM_CODE_LENGTH_CODES 19 static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = { 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; #define CODE_TO_PLANE_CODES 120 static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = { 0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a, 0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a, 0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b, 0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03, 0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c, 0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e, 0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b, 0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f, 0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b, 0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41, 0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f, 0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70 }; static int DecodeImageStream(int xsize, int ysize, int is_level0, VP8LDecoder* const dec, uint32_t** const decoded_data); //------------------------------------------------------------------------------ int VP8LCheckSignature(const uint8_t* const data, size_t size) { return (size >= VP8L_FRAME_HEADER_SIZE && data[0] == VP8L_MAGIC_BYTE && (data[4] >> 5) == 0); // version } static int ReadImageInfo(VP8LBitReader* const br, int* const width, int* const height, int* const has_alpha) { if (VP8LReadBits(br, 8) != VP8L_MAGIC_BYTE) return 0; *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; *has_alpha = VP8LReadBits(br, 1); if (VP8LReadBits(br, VP8L_VERSION_BITS) != 0) return 0; return 1; } int VP8LGetInfo(const uint8_t* data, size_t data_size, int* const width, int* const height, int* const has_alpha) { if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) { return 0; // not enough data } else if (!VP8LCheckSignature(data, data_size)) { return 0; // bad signature } else { int w, h, a; VP8LBitReader br; VP8LInitBitReader(&br, data, data_size); if (!ReadImageInfo(&br, &w, &h, &a)) { return 0; } if (width != NULL) *width = w; if (height != NULL) *height = h; if (has_alpha != NULL) *has_alpha = a; return 1; } } //------------------------------------------------------------------------------ static WEBP_INLINE int GetCopyDistance(int distance_symbol, VP8LBitReader* const br) { int extra_bits, offset; if (distance_symbol < 4) { return distance_symbol + 1; } extra_bits = (distance_symbol - 2) >> 1; offset = (2 + (distance_symbol & 1)) << extra_bits; return offset + VP8LReadBits(br, extra_bits) + 1; } static WEBP_INLINE int GetCopyLength(int length_symbol, VP8LBitReader* const br) { // Length and distance prefixes are encoded the same way. return GetCopyDistance(length_symbol, br); } static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) { if (plane_code > CODE_TO_PLANE_CODES) { return plane_code - CODE_TO_PLANE_CODES; } else { const int dist_code = kCodeToPlane[plane_code - 1]; const int yoffset = dist_code >> 4; const int xoffset = 8 - (dist_code & 0xf); const int dist = yoffset * xsize + xoffset; return (dist >= 1) ? dist : 1; // dist<1 can happen if xsize is very small } } //------------------------------------------------------------------------------ // Decodes the next Huffman code from bit-stream. // FillBitWindow(br) needs to be called at minimum every second call // to ReadSymbol, in order to pre-fetch enough bits. static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, VP8LBitReader* const br) { const HuffmanTreeNode* node = tree->root_; uint32_t bits = VP8LPrefetchBits(br); int bitpos = br->bit_pos_; // Check if we find the bit combination from the Huffman lookup table. const int lut_ix = bits & (HUFF_LUT - 1); const int lut_bits = tree->lut_bits_[lut_ix]; if (lut_bits <= HUFF_LUT_BITS) { VP8LSetBitPos(br, bitpos + lut_bits); return tree->lut_symbol_[lut_ix]; } node += tree->lut_jump_[lut_ix]; bitpos += HUFF_LUT_BITS; bits >>= HUFF_LUT_BITS; // Decode the value from a binary tree. assert(node != NULL); do { node = HuffmanTreeNextNode(node, bits & 1); bits >>= 1; ++bitpos; } while (HuffmanTreeNodeIsNotLeaf(node)); VP8LSetBitPos(br, bitpos); return node->symbol_; } static int ReadHuffmanCodeLengths( VP8LDecoder* const dec, const int* const code_length_code_lengths, int num_symbols, int* const code_lengths) { int ok = 0; VP8LBitReader* const br = &dec->br_; int symbol; int max_symbol; int prev_code_len = DEFAULT_CODE_LENGTH; HuffmanTree tree; if (!HuffmanTreeBuildImplicit(&tree, code_length_code_lengths, NUM_CODE_LENGTH_CODES)) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return 0; } if (VP8LReadBits(br, 1)) { // use length const int length_nbits = 2 + 2 * VP8LReadBits(br, 3); max_symbol = 2 + VP8LReadBits(br, length_nbits); if (max_symbol > num_symbols) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto End; } } else { max_symbol = num_symbols; } symbol = 0; while (symbol < num_symbols) { int code_len; if (max_symbol-- == 0) break; VP8LFillBitWindow(br); code_len = ReadSymbol(&tree, br); if (code_len < kCodeLengthLiterals) { code_lengths[symbol++] = code_len; if (code_len != 0) prev_code_len = code_len; } else { const int use_prev = (code_len == kCodeLengthRepeatCode); const int slot = code_len - kCodeLengthLiterals; const int extra_bits = kCodeLengthExtraBits[slot]; const int repeat_offset = kCodeLengthRepeatOffsets[slot]; int repeat = VP8LReadBits(br, extra_bits) + repeat_offset; if (symbol + repeat > num_symbols) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto End; } else { const int length = use_prev ? prev_code_len : 0; while (repeat-- > 0) code_lengths[symbol++] = length; } } } ok = 1; End: HuffmanTreeRelease(&tree); return ok; } static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec, HuffmanTree* const tree) { int ok = 0; VP8LBitReader* const br = &dec->br_; const int simple_code = VP8LReadBits(br, 1); if (simple_code) { // Read symbols, codes & code lengths directly. int symbols[2]; int codes[2]; int code_lengths[2]; const int num_symbols = VP8LReadBits(br, 1) + 1; const int first_symbol_len_code = VP8LReadBits(br, 1); // The first code is either 1 bit or 8 bit code. symbols[0] = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8); codes[0] = 0; code_lengths[0] = num_symbols - 1; // The second code (if present), is always 8 bit long. if (num_symbols == 2) { symbols[1] = VP8LReadBits(br, 8); codes[1] = 1; code_lengths[1] = num_symbols - 1; } ok = HuffmanTreeBuildExplicit(tree, code_lengths, codes, symbols, alphabet_size, num_symbols); } else { // Decode Huffman-coded code lengths. int* code_lengths = NULL; int i; int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; const int num_codes = VP8LReadBits(br, 4) + 4; if (num_codes > NUM_CODE_LENGTH_CODES) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return 0; } code_lengths = (int*)WebPSafeCalloc((uint64_t)alphabet_size, sizeof(*code_lengths)); if (code_lengths == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; return 0; } for (i = 0; i < num_codes; ++i) { code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3); } ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size, code_lengths); if (ok) { ok = HuffmanTreeBuildImplicit(tree, code_lengths, alphabet_size); } free(code_lengths); } ok = ok && !br->error_; if (!ok) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; return 0; } return 1; } static void DeleteHtreeGroups(HTreeGroup* htree_groups, int num_htree_groups) { if (htree_groups != NULL) { int i, j; for (i = 0; i < num_htree_groups; ++i) { HuffmanTree* const htrees = htree_groups[i].htrees_; for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { HuffmanTreeRelease(&htrees[j]); } } free(htree_groups); } } static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, int color_cache_bits, int allow_recursion) { int i, j; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; uint32_t* huffman_image = NULL; HTreeGroup* htree_groups = NULL; int num_htree_groups = 1; if (allow_recursion && VP8LReadBits(br, 1)) { // use meta Huffman codes. const int huffman_precision = VP8LReadBits(br, 3) + 2; const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision); const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision); const int huffman_pixs = huffman_xsize * huffman_ysize; if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec, &huffman_image)) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto Error; } hdr->huffman_subsample_bits_ = huffman_precision; for (i = 0; i < huffman_pixs; ++i) { // The huffman data is stored in red and green bytes. const int group = (huffman_image[i] >> 8) & 0xffff; huffman_image[i] = group; if (group >= num_htree_groups) { num_htree_groups = group + 1; } } } if (br->error_) goto Error; assert(num_htree_groups <= 0x10000); htree_groups = (HTreeGroup*)WebPSafeCalloc((uint64_t)num_htree_groups, sizeof(*htree_groups)); if (htree_groups == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; goto Error; } for (i = 0; i < num_htree_groups; ++i) { HuffmanTree* const htrees = htree_groups[i].htrees_; for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { int alphabet_size = kAlphabetSize[j]; if (j == 0 && color_cache_bits > 0) { alphabet_size += 1 << color_cache_bits; } if (!ReadHuffmanCode(alphabet_size, dec, htrees + j)) goto Error; } } // All OK. Finalize pointers and return. hdr->huffman_image_ = huffman_image; hdr->num_htree_groups_ = num_htree_groups; hdr->htree_groups_ = htree_groups; return 1; Error: free(huffman_image); DeleteHtreeGroups(htree_groups, num_htree_groups); return 0; } //------------------------------------------------------------------------------ // Scaling. static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) { const int num_channels = 4; const int in_width = io->mb_w; const int out_width = io->scaled_width; const int in_height = io->mb_h; const int out_height = io->scaled_height; const uint64_t work_size = 2 * num_channels * (uint64_t)out_width; int32_t* work; // Rescaler work area. const uint64_t scaled_data_size = num_channels * (uint64_t)out_width; uint32_t* scaled_data; // Temporary storage for scaled BGRA data. const uint64_t memory_size = sizeof(*dec->rescaler) + work_size * sizeof(*work) + scaled_data_size * sizeof(*scaled_data); uint8_t* memory = (uint8_t*)WebPSafeCalloc(memory_size, sizeof(*memory)); if (memory == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; return 0; } assert(dec->rescaler_memory == NULL); dec->rescaler_memory = memory; dec->rescaler = (WebPRescaler*)memory; memory += sizeof(*dec->rescaler); work = (int32_t*)memory; memory += work_size * sizeof(*work); scaled_data = (uint32_t*)memory; WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data, out_width, out_height, 0, num_channels, in_width, out_width, in_height, out_height, work); return 1; } //------------------------------------------------------------------------------ // Export to ARGB // We have special "export" function since we need to convert from BGRA static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace, int rgba_stride, uint8_t* const rgba) { uint32_t* const src = (uint32_t*)rescaler->dst; const int dst_width = rescaler->dst_width; int num_lines_out = 0; while (WebPRescalerHasPendingOutput(rescaler)) { uint8_t* const dst = rgba + num_lines_out * rgba_stride; WebPRescalerExportRow(rescaler); WebPMultARGBRow(src, dst_width, 1); VP8LConvertFromBGRA(src, dst_width, colorspace, dst); ++num_lines_out; } return num_lines_out; } // Emit scaled rows. static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec, uint8_t* in, int in_stride, int mb_h, uint8_t* const out, int out_stride) { const WEBP_CSP_MODE colorspace = dec->output_->colorspace; int num_lines_in = 0; int num_lines_out = 0; while (num_lines_in < mb_h) { uint8_t* const row_in = in + num_lines_in * in_stride; uint8_t* const row_out = out + num_lines_out * out_stride; const int lines_left = mb_h - num_lines_in; const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left); assert(needed_lines > 0 && needed_lines <= lines_left); WebPMultARGBRows(row_in, in_stride, dec->rescaler->src_width, needed_lines, 0); WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride); num_lines_in += needed_lines; num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out); } return num_lines_out; } // Emit rows without any scaling. static int EmitRows(WEBP_CSP_MODE colorspace, const uint8_t* row_in, int in_stride, int mb_w, int mb_h, uint8_t* const out, int out_stride) { int lines = mb_h; uint8_t* row_out = out; while (lines-- > 0) { VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out); row_in += in_stride; row_out += out_stride; } return mb_h; // Num rows out == num rows in. } //------------------------------------------------------------------------------ // Export to YUVA static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos, const WebPDecBuffer* const output) { const WebPYUVABuffer* const buf = &output->u.YUVA; // first, the luma plane { int i; uint8_t* const y = buf->y + y_pos * buf->y_stride; for (i = 0; i < width; ++i) { const uint32_t p = src[i]; y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff, YUV_HALF); } } // then U/V planes { uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride; uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride; const int uv_width = width >> 1; int i; for (i = 0; i < uv_width; ++i) { const uint32_t v0 = src[2 * i + 0]; const uint32_t v1 = src[2 * i + 1]; // VP8RGBToU/V expects four accumulated pixels. Hence we need to // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less. const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe); const int g = ((v0 >> 7) & 0x1fe) + ((v1 >> 7) & 0x1fe); const int b = ((v0 << 1) & 0x1fe) + ((v1 << 1) & 0x1fe); if (!(y_pos & 1)) { // even lines: store values u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); } else { // odd lines: average with previous values const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2); const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2); // Approximated average-of-four. But it's an acceptable diff. u[i] = (u[i] + tmp_u + 1) >> 1; v[i] = (v[i] + tmp_v + 1) >> 1; } } if (width & 1) { // last pixel const uint32_t v0 = src[2 * i + 0]; const int r = (v0 >> 14) & 0x3fc; const int g = (v0 >> 6) & 0x3fc; const int b = (v0 << 2) & 0x3fc; if (!(y_pos & 1)) { // even lines u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); } else { // odd lines (note: we could just skip this) const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2); const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2); u[i] = (u[i] + tmp_u + 1) >> 1; v[i] = (v[i] + tmp_v + 1) >> 1; } } } // Lastly, store alpha if needed. if (buf->a != NULL) { int i; uint8_t* const a = buf->a + y_pos * buf->a_stride; for (i = 0; i < width; ++i) a[i] = (src[i] >> 24); } } static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) { WebPRescaler* const rescaler = dec->rescaler; uint32_t* const src = (uint32_t*)rescaler->dst; const int dst_width = rescaler->dst_width; int num_lines_out = 0; while (WebPRescalerHasPendingOutput(rescaler)) { WebPRescalerExportRow(rescaler); WebPMultARGBRow(src, dst_width, 1); ConvertToYUVA(src, dst_width, y_pos, dec->output_); ++y_pos; ++num_lines_out; } return num_lines_out; } static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec, uint8_t* in, int in_stride, int mb_h) { int num_lines_in = 0; int y_pos = dec->last_out_row_; while (num_lines_in < mb_h) { const int lines_left = mb_h - num_lines_in; const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left); WebPMultARGBRows(in, in_stride, dec->rescaler->src_width, needed_lines, 0); WebPRescalerImport(dec->rescaler, lines_left, in, in_stride); num_lines_in += needed_lines; in += needed_lines * in_stride; y_pos += ExportYUVA(dec, y_pos); } return y_pos; } static int EmitRowsYUVA(const VP8LDecoder* const dec, const uint8_t* in, int in_stride, int mb_w, int num_rows) { int y_pos = dec->last_out_row_; while (num_rows-- > 0) { ConvertToYUVA((const uint32_t*)in, mb_w, y_pos, dec->output_); in += in_stride; ++y_pos; } return y_pos; } //------------------------------------------------------------------------------ // Cropping. // Sets io->mb_y, io->mb_h & io->mb_w according to start row, end row and // crop options. Also updates the input data pointer, so that it points to the // start of the cropped window. Note that pixels are in ARGB format even if // 'in_data' is uint8_t*. // Returns true if the crop window is not empty. static int SetCropWindow(VP8Io* const io, int y_start, int y_end, uint8_t** const in_data, int pixel_stride) { assert(y_start < y_end); assert(io->crop_left < io->crop_right); if (y_end > io->crop_bottom) { y_end = io->crop_bottom; // make sure we don't overflow on last row. } if (y_start < io->crop_top) { const int delta = io->crop_top - y_start; y_start = io->crop_top; *in_data += delta * pixel_stride; } if (y_start >= y_end) return 0; // Crop window is empty. *in_data += io->crop_left * sizeof(uint32_t); io->mb_y = y_start - io->crop_top; io->mb_w = io->crop_right - io->crop_left; io->mb_h = y_end - y_start; return 1; // Non-empty crop window. } //------------------------------------------------------------------------------ static WEBP_INLINE int GetMetaIndex( const uint32_t* const image, int xsize, int bits, int x, int y) { if (bits == 0) return 0; return image[xsize * (y >> bits) + (x >> bits)]; } static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr, int x, int y) { const int meta_index = GetMetaIndex(hdr->huffman_image_, hdr->huffman_xsize_, hdr->huffman_subsample_bits_, x, y); assert(meta_index < hdr->num_htree_groups_); return hdr->htree_groups_ + meta_index; } //------------------------------------------------------------------------------ // Main loop, with custom row-processing function typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row); static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows, const uint32_t* const rows) { int n = dec->next_transform_; const int cache_pixs = dec->width_ * num_rows; const int start_row = dec->last_row_; const int end_row = start_row + num_rows; const uint32_t* rows_in = rows; uint32_t* const rows_out = dec->argb_cache_; // Inverse transforms. // TODO: most transforms only need to operate on the cropped region only. memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); while (n-- > 0) { VP8LTransform* const transform = &dec->transforms_[n]; VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out); rows_in = rows_out; } } // Special method for paletted alpha data. static void ApplyInverseTransformsAlpha(VP8LDecoder* const dec, int num_rows, const uint8_t* const rows) { const int start_row = dec->last_row_; const int end_row = start_row + num_rows; const uint8_t* rows_in = rows; uint8_t* rows_out = (uint8_t*)dec->io_->opaque + dec->io_->width * start_row; VP8LTransform* const transform = &dec->transforms_[0]; assert(dec->next_transform_ == 1); assert(transform->type_ == COLOR_INDEXING_TRANSFORM); VP8LColorIndexInverseTransformAlpha(transform, start_row, end_row, rows_in, rows_out); } // Processes (transforms, scales & color-converts) the rows decoded after the // last call. static void ProcessRows(VP8LDecoder* const dec, int row) { const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_; const int num_rows = row - dec->last_row_; if (num_rows <= 0) return; // Nothing to be done. ApplyInverseTransforms(dec, num_rows, rows); // Emit output. { VP8Io* const io = dec->io_; uint8_t* rows_data = (uint8_t*)dec->argb_cache_; const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) { // Nothing to output (this time). } else { const WebPDecBuffer* const output = dec->output_; if (output->colorspace < MODE_YUV) { // convert to RGBA const WebPRGBABuffer* const buf = &output->u.RGBA; uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride; const int num_rows_out = io->use_scaling ? EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h, rgba, buf->stride) : EmitRows(output->colorspace, rows_data, in_stride, io->mb_w, io->mb_h, rgba, buf->stride); // Update 'last_out_row_'. dec->last_out_row_ += num_rows_out; } else { // convert to YUVA dec->last_out_row_ = io->use_scaling ? EmitRescaledRowsYUVA(dec, rows_data, in_stride, io->mb_h) : EmitRowsYUVA(dec, rows_data, in_stride, io->mb_w, io->mb_h); } assert(dec->last_out_row_ <= output->height); } } // Update 'last_row_'. dec->last_row_ = row; assert(dec->last_row_ <= dec->height_); } // Row-processing for the special case when alpha data contains only one // transform (color indexing), and trivial non-green literals. static int Is8bOptimizable(const VP8LMetadata* const hdr) { int i; if (hdr->color_cache_size_ > 0) return 0; // When the Huffman tree contains only one symbol, we can skip the // call to ReadSymbol() for red/blue/alpha channels. for (i = 0; i < hdr->num_htree_groups_; ++i) { const HuffmanTree* const htrees = hdr->htree_groups_[i].htrees_; if (htrees[RED].num_nodes_ > 1) return 0; if (htrees[BLUE].num_nodes_ > 1) return 0; if (htrees[ALPHA].num_nodes_ > 1) return 0; } return 1; } static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int row) { const int num_rows = row - dec->last_row_; const uint8_t* const in = (uint8_t*)dec->pixels_ + dec->width_ * dec->last_row_; if (num_rows > 0) { ApplyInverseTransformsAlpha(dec, num_rows, in); } dec->last_row_ = dec->last_out_row_ = row; } static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data, int width, int height, int last_row) { int ok = 1; int row = dec->last_pixel_ / width; int col = dec->last_pixel_ % width; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; const HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row); int pos = dec->last_pixel_; // current position const int end = width * height; // End of data const int last = width * last_row; // Last pixel to decode const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; const int mask = hdr->huffman_mask_; assert(htree_group != NULL); assert(last_row <= height); assert(Is8bOptimizable(hdr)); while (!br->eos_ && pos < last) { int code; // Only update when changing tile. if ((col & mask) == 0) { htree_group = GetHtreeGroupForPos(hdr, col, row); } VP8LFillBitWindow(br); code = ReadSymbol(&htree_group->htrees_[GREEN], br); if (code < NUM_LITERAL_CODES) { // Literal data[pos] = code; ++pos; ++col; if (col >= width) { col = 0; ++row; if (row % NUM_ARGB_CACHE_ROWS == 0) { ExtractPalettedAlphaRows(dec, row); } } } else if (code < len_code_limit) { // Backward reference int dist_code, dist; const int length_sym = code - NUM_LITERAL_CODES; const int length = GetCopyLength(length_sym, br); const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br); VP8LFillBitWindow(br); dist_code = GetCopyDistance(dist_symbol, br); dist = PlaneCodeToDistance(width, dist_code); if (pos >= dist && end - pos >= length) { int i; for (i = 0; i < length; ++i) data[pos + i] = data[pos + i - dist]; } else { ok = 0; goto End; } pos += length; col += length; while (col >= width) { col -= width; ++row; if (row % NUM_ARGB_CACHE_ROWS == 0) { ExtractPalettedAlphaRows(dec, row); } } if (pos < last && (col & mask)) { htree_group = GetHtreeGroupForPos(hdr, col, row); } } else { // Not reached ok = 0; goto End; } ok = !br->error_; if (!ok) goto End; } // Process the remaining rows corresponding to last row-block. ExtractPalettedAlphaRows(dec, row); End: if (br->error_ || !ok || (br->eos_ && pos < end)) { ok = 0; dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED : VP8_STATUS_BITSTREAM_ERROR; } else { dec->last_pixel_ = (int)pos; if (pos == end) dec->state_ = READ_DATA; } return ok; } static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data, int width, int height, int last_row, ProcessRowsFunc process_func) { int ok = 1; int row = dec->last_pixel_ / width; int col = dec->last_pixel_ % width; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row); uint32_t* src = data + dec->last_pixel_; uint32_t* last_cached = src; uint32_t* const src_end = data + width * height; // End of data uint32_t* const src_last = data + width * last_row; // Last pixel to decode const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; const int color_cache_limit = len_code_limit + hdr->color_cache_size_; VP8LColorCache* const color_cache = (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL; const int mask = hdr->huffman_mask_; assert(htree_group != NULL); assert(src_last <= src_end); while (!br->eos_ && src < src_last) { int code; // Only update when changing tile. Note we could use this test: // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed // but that's actually slower and needs storing the previous col/row. if ((col & mask) == 0) { htree_group = GetHtreeGroupForPos(hdr, col, row); } VP8LFillBitWindow(br); code = ReadSymbol(&htree_group->htrees_[GREEN], br); if (code < NUM_LITERAL_CODES) { // Literal int red, green, blue, alpha; red = ReadSymbol(&htree_group->htrees_[RED], br); green = code; VP8LFillBitWindow(br); blue = ReadSymbol(&htree_group->htrees_[BLUE], br); alpha = ReadSymbol(&htree_group->htrees_[ALPHA], br); *src = (alpha << 24) | (red << 16) | (green << 8) | blue; AdvanceByOne: ++src; ++col; if (col >= width) { col = 0; ++row; if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { process_func(dec, row); } if (color_cache != NULL) { while (last_cached < src) { VP8LColorCacheInsert(color_cache, *last_cached++); } } } } else if (code < len_code_limit) { // Backward reference int dist_code, dist; const int length_sym = code - NUM_LITERAL_CODES; const int length = GetCopyLength(length_sym, br); const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br); VP8LFillBitWindow(br); dist_code = GetCopyDistance(dist_symbol, br); dist = PlaneCodeToDistance(width, dist_code); if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { ok = 0; goto End; } else { int i; for (i = 0; i < length; ++i) src[i] = src[i - dist]; src += length; } col += length; while (col >= width) { col -= width; ++row; if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { process_func(dec, row); } } if (src < src_last) { if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row); if (color_cache != NULL) { while (last_cached < src) { VP8LColorCacheInsert(color_cache, *last_cached++); } } } } else if (code < color_cache_limit) { // Color cache const int key = code - len_code_limit; assert(color_cache != NULL); while (last_cached < src) { VP8LColorCacheInsert(color_cache, *last_cached++); } *src = VP8LColorCacheLookup(color_cache, key); goto AdvanceByOne; } else { // Not reached ok = 0; goto End; } ok = !br->error_; if (!ok) goto End; } // Process the remaining rows corresponding to last row-block. if (process_func != NULL) process_func(dec, row); End: if (br->error_ || !ok || (br->eos_ && src < src_end)) { ok = 0; dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED : VP8_STATUS_BITSTREAM_ERROR; } else { dec->last_pixel_ = (int)(src - data); if (src == src_end) dec->state_ = READ_DATA; } return ok; } // ----------------------------------------------------------------------------- // VP8LTransform static void ClearTransform(VP8LTransform* const transform) { free(transform->data_); transform->data_ = NULL; } // For security reason, we need to remap the color map to span // the total possible bundled values, and not just the num_colors. static int ExpandColorMap(int num_colors, VP8LTransform* const transform) { int i; const int final_num_colors = 1 << (8 >> transform->bits_); uint32_t* const new_color_map = (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors, sizeof(*new_color_map)); if (new_color_map == NULL) { return 0; } else { uint8_t* const data = (uint8_t*)transform->data_; uint8_t* const new_data = (uint8_t*)new_color_map; new_color_map[0] = transform->data_[0]; for (i = 4; i < 4 * num_colors; ++i) { // Equivalent to AddPixelEq(), on a byte-basis. new_data[i] = (data[i] + new_data[i - 4]) & 0xff; } for (; i < 4 * final_num_colors; ++i) new_data[i] = 0; // black tail. free(transform->data_); transform->data_ = new_color_map; } return 1; } static int ReadTransform(int* const xsize, int const* ysize, VP8LDecoder* const dec) { int ok = 1; VP8LBitReader* const br = &dec->br_; VP8LTransform* transform = &dec->transforms_[dec->next_transform_]; const VP8LImageTransformType type = (VP8LImageTransformType)VP8LReadBits(br, 2); // Each transform type can only be present once in the stream. if (dec->transforms_seen_ & (1U << type)) { return 0; // Already there, let's not accept the second same transform. } dec->transforms_seen_ |= (1U << type); transform->type_ = type; transform->xsize_ = *xsize; transform->ysize_ = *ysize; transform->data_ = NULL; ++dec->next_transform_; assert(dec->next_transform_ <= NUM_TRANSFORMS); switch (type) { case PREDICTOR_TRANSFORM: case CROSS_COLOR_TRANSFORM: transform->bits_ = VP8LReadBits(br, 3) + 2; ok = DecodeImageStream(VP8LSubSampleSize(transform->xsize_, transform->bits_), VP8LSubSampleSize(transform->ysize_, transform->bits_), 0, dec, &transform->data_); break; case COLOR_INDEXING_TRANSFORM: { const int num_colors = VP8LReadBits(br, 8) + 1; const int bits = (num_colors > 16) ? 0 : (num_colors > 4) ? 1 : (num_colors > 2) ? 2 : 3; *xsize = VP8LSubSampleSize(transform->xsize_, bits); transform->bits_ = bits; ok = DecodeImageStream(num_colors, 1, 0, dec, &transform->data_); ok = ok && ExpandColorMap(num_colors, transform); break; } case SUBTRACT_GREEN: break; default: assert(0); // can't happen break; } return ok; } // ----------------------------------------------------------------------------- // VP8LMetadata static void InitMetadata(VP8LMetadata* const hdr) { assert(hdr); memset(hdr, 0, sizeof(*hdr)); } static void ClearMetadata(VP8LMetadata* const hdr) { assert(hdr); free(hdr->huffman_image_); DeleteHtreeGroups(hdr->htree_groups_, hdr->num_htree_groups_); VP8LColorCacheClear(&hdr->color_cache_); InitMetadata(hdr); } // ----------------------------------------------------------------------------- // VP8LDecoder VP8LDecoder* VP8LNew(void) { VP8LDecoder* const dec = (VP8LDecoder*)calloc(1, sizeof(*dec)); if (dec == NULL) return NULL; dec->status_ = VP8_STATUS_OK; dec->action_ = READ_DIM; dec->state_ = READ_DIM; VP8LDspInit(); // Init critical function pointers. return dec; } void VP8LClear(VP8LDecoder* const dec) { int i; if (dec == NULL) return; ClearMetadata(&dec->hdr_); free(dec->pixels_); dec->pixels_ = NULL; for (i = 0; i < dec->next_transform_; ++i) { ClearTransform(&dec->transforms_[i]); } dec->next_transform_ = 0; dec->transforms_seen_ = 0; free(dec->rescaler_memory); dec->rescaler_memory = NULL; dec->output_ = NULL; // leave no trace behind } void VP8LDelete(VP8LDecoder* const dec) { if (dec != NULL) { VP8LClear(dec); free(dec); } } static void UpdateDecoder(VP8LDecoder* const dec, int width, int height) { VP8LMetadata* const hdr = &dec->hdr_; const int num_bits = hdr->huffman_subsample_bits_; dec->width_ = width; dec->height_ = height; hdr->huffman_xsize_ = VP8LSubSampleSize(width, num_bits); hdr->huffman_mask_ = (num_bits == 0) ? ~0 : (1 << num_bits) - 1; } static int DecodeImageStream(int xsize, int ysize, int is_level0, VP8LDecoder* const dec, uint32_t** const decoded_data) { int ok = 1; int transform_xsize = xsize; int transform_ysize = ysize; VP8LBitReader* const br = &dec->br_; VP8LMetadata* const hdr = &dec->hdr_; uint32_t* data = NULL; int color_cache_bits = 0; // Read the transforms (may recurse). if (is_level0) { while (ok && VP8LReadBits(br, 1)) { ok = ReadTransform(&transform_xsize, &transform_ysize, dec); } } // Color cache if (ok && VP8LReadBits(br, 1)) { color_cache_bits = VP8LReadBits(br, 4); ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS); if (!ok) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto End; } } // Read the Huffman codes (may recurse). ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize, color_cache_bits, is_level0); if (!ok) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto End; } // Finish setting up the color-cache if (color_cache_bits > 0) { hdr->color_cache_size_ = 1 << color_cache_bits; if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; ok = 0; goto End; } } else { hdr->color_cache_size_ = 0; } UpdateDecoder(dec, transform_xsize, transform_ysize); if (is_level0) { // level 0 complete dec->state_ = READ_HDR; goto End; } { const uint64_t total_size = (uint64_t)transform_xsize * transform_ysize; data = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*data)); if (data == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; ok = 0; goto End; } } // Use the Huffman trees to decode the LZ77 encoded data. ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, transform_ysize, NULL); ok = ok && !br->error_; End: if (!ok) { free(data); ClearMetadata(hdr); // If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the // status appropriately. if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR && dec->br_.eos_) { dec->status_ = VP8_STATUS_SUSPENDED; } } else { if (decoded_data != NULL) { *decoded_data = data; } else { // We allocate image data in this function only for transforms. At level 0 // (that is: not the transforms), we shouldn't have allocated anything. assert(data == NULL); assert(is_level0); } dec->last_pixel_ = 0; // Reset for future DECODE_DATA_FUNC() calls. if (!is_level0) ClearMetadata(hdr); // Clean up temporary data behind. } return ok; } //------------------------------------------------------------------------------ // Allocate internal buffers dec->pixels_ and dec->argb_cache_. static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) { const uint64_t num_pixels = (uint64_t)dec->width_ * dec->height_; // Scratch buffer corresponding to top-prediction row for transforming the // first row in the row-blocks. Not needed for paletted alpha. const uint64_t cache_top_pixels = (uint16_t)final_width; // Scratch buffer for temporary BGRA storage. Not needed for paletted alpha. const uint64_t cache_pixels = (uint64_t)final_width * NUM_ARGB_CACHE_ROWS; const uint64_t total_num_pixels = num_pixels + cache_top_pixels + cache_pixels; assert(dec->width_ <= final_width); dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t)); if (dec->pixels_ == NULL) { dec->argb_cache_ = NULL; // for sanity check dec->status_ = VP8_STATUS_OUT_OF_MEMORY; return 0; } dec->argb_cache_ = dec->pixels_ + num_pixels + cache_top_pixels; return 1; } static int AllocateInternalBuffers8b(VP8LDecoder* const dec) { const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_; dec->argb_cache_ = NULL; // for sanity check dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t)); if (dec->pixels_ == NULL) { dec->status_ = VP8_STATUS_OUT_OF_MEMORY; return 0; } return 1; } //------------------------------------------------------------------------------ // Special row-processing that only stores the alpha data. static void ExtractAlphaRows(VP8LDecoder* const dec, int row) { const int num_rows = row - dec->last_row_; const uint32_t* const in = dec->pixels_ + dec->width_ * dec->last_row_; if (num_rows <= 0) return; // Nothing to be done. ApplyInverseTransforms(dec, num_rows, in); // Extract alpha (which is stored in the green plane). { const int width = dec->io_->width; // the final width (!= dec->width_) const int cache_pixs = width * num_rows; uint8_t* const dst = (uint8_t*)dec->io_->opaque + width * dec->last_row_; const uint32_t* const src = dec->argb_cache_; int i; for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff; } dec->last_row_ = dec->last_out_row_ = row; } int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec, const uint8_t* const data, size_t data_size, uint8_t* const output) { int ok = 0; VP8LDecoder* dec; VP8Io* io; assert(alph_dec != NULL); alph_dec->vp8l_dec_ = VP8LNew(); if (alph_dec->vp8l_dec_ == NULL) return 0; dec = alph_dec->vp8l_dec_; dec->width_ = alph_dec->width_; dec->height_ = alph_dec->height_; dec->io_ = &alph_dec->io_; io = dec->io_; VP8InitIo(io); WebPInitCustomIo(NULL, io); // Just a sanity Init. io won't be used. io->opaque = output; io->width = alph_dec->width_; io->height = alph_dec->height_; dec->status_ = VP8_STATUS_OK; VP8LInitBitReader(&dec->br_, data, data_size); dec->action_ = READ_HDR; if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) { goto Err; } // Special case: if alpha data uses only the color indexing transform and // doesn't use color cache (a frequent case), we will use DecodeAlphaData() // method that only needs allocation of 1 byte per pixel (alpha channel). if (dec->next_transform_ == 1 && dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM && Is8bOptimizable(&dec->hdr_)) { alph_dec->use_8b_decode = 1; ok = AllocateInternalBuffers8b(dec); } else { // Allocate internal buffers (note that dec->width_ may have changed here). alph_dec->use_8b_decode = 0; ok = AllocateInternalBuffers32b(dec, alph_dec->width_); } if (!ok) goto Err; dec->action_ = READ_DATA; return 1; Err: VP8LDelete(alph_dec->vp8l_dec_); alph_dec->vp8l_dec_ = NULL; return 0; } int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) { VP8LDecoder* const dec = alph_dec->vp8l_dec_; assert(dec != NULL); assert(dec->action_ == READ_DATA); assert(last_row <= dec->height_); // Decode (with special row processing). return alph_dec->use_8b_decode ? DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_, last_row) : DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_, last_row, ExtractAlphaRows); } //------------------------------------------------------------------------------ int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) { int width, height, has_alpha; if (dec == NULL) return 0; if (io == NULL) { dec->status_ = VP8_STATUS_INVALID_PARAM; return 0; } dec->io_ = io; dec->status_ = VP8_STATUS_OK; VP8LInitBitReader(&dec->br_, io->data, io->data_size); if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) { dec->status_ = VP8_STATUS_BITSTREAM_ERROR; goto Error; } dec->state_ = READ_DIM; io->width = width; io->height = height; dec->action_ = READ_HDR; if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error; return 1; Error: VP8LClear(dec); assert(dec->status_ != VP8_STATUS_OK); return 0; } int VP8LDecodeImage(VP8LDecoder* const dec) { VP8Io* io = NULL; WebPDecParams* params = NULL; // Sanity checks. if (dec == NULL) return 0; io = dec->io_; assert(io != NULL); params = (WebPDecParams*)io->opaque; assert(params != NULL); dec->output_ = params->output; assert(dec->output_ != NULL); // Initialization. if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) { dec->status_ = VP8_STATUS_INVALID_PARAM; goto Err; } if (!AllocateInternalBuffers32b(dec, io->width)) goto Err; if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err; // Decode. dec->action_ = READ_DATA; if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_, dec->height_, ProcessRows)) { goto Err; } // Cleanup. params->last_y = dec->last_out_row_; VP8LClear(dec); return 1; Err: VP8LClear(dec); assert(dec->status_ != VP8_STATUS_OK); return 0; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/vp8.c0000644000014400001440000005126412255002107012254 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // main entry for the decoder // // Author: Skal (pascal.massimino@gmail.com) #include #include "./alphai.h" #include "./vp8i.h" #include "./vp8li.h" #include "./webpi.h" #include "../utils/bit_reader.h" //------------------------------------------------------------------------------ int WebPGetDecoderVersion(void) { return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION; } //------------------------------------------------------------------------------ // VP8Decoder static void SetOk(VP8Decoder* const dec) { dec->status_ = VP8_STATUS_OK; dec->error_msg_ = "OK"; } int VP8InitIoInternal(VP8Io* const io, int version) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { return 0; // mismatch error } if (io != NULL) { memset(io, 0, sizeof(*io)); } return 1; } VP8Decoder* VP8New(void) { VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec)); if (dec != NULL) { SetOk(dec); WebPWorkerInit(&dec->worker_); dec->ready_ = 0; dec->num_parts_ = 1; } return dec; } VP8StatusCode VP8Status(VP8Decoder* const dec) { if (!dec) return VP8_STATUS_INVALID_PARAM; return dec->status_; } const char* VP8StatusMessage(VP8Decoder* const dec) { if (dec == NULL) return "no object"; if (!dec->error_msg_) return "OK"; return dec->error_msg_; } void VP8Delete(VP8Decoder* const dec) { if (dec != NULL) { VP8Clear(dec); free(dec); } } int VP8SetError(VP8Decoder* const dec, VP8StatusCode error, const char* const msg) { // TODO This check would be unnecessary if alpha decompression was separated // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression // failure. if (dec->status_ == VP8_STATUS_OK) { dec->status_ = error; dec->error_msg_ = msg; dec->ready_ = 0; } return 0; } //------------------------------------------------------------------------------ int VP8CheckSignature(const uint8_t* const data, size_t data_size) { return (data_size >= 3 && data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a); } int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size, int* const width, int* const height) { if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) { return 0; // not enough data } // check signature if (!VP8CheckSignature(data + 3, data_size - 3)) { return 0; // Wrong signature. } else { const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); const int key_frame = !(bits & 1); const int w = ((data[7] << 8) | data[6]) & 0x3fff; const int h = ((data[9] << 8) | data[8]) & 0x3fff; if (!key_frame) { // Not a keyframe. return 0; } if (((bits >> 1) & 7) > 3) { return 0; // unknown profile } if (!((bits >> 4) & 1)) { return 0; // first frame is invisible! } if (((bits >> 5)) >= chunk_size) { // partition_length return 0; // inconsistent size information. } if (w == 0 || h == 0) { return 0; // We don't support both width and height to be zero. } if (width) { *width = w; } if (height) { *height = h; } return 1; } } //------------------------------------------------------------------------------ // Header parsing static void ResetSegmentHeader(VP8SegmentHeader* const hdr) { assert(hdr != NULL); hdr->use_segment_ = 0; hdr->update_map_ = 0; hdr->absolute_delta_ = 1; memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_)); memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_)); } // Paragraph 9.3 static int ParseSegmentHeader(VP8BitReader* br, VP8SegmentHeader* hdr, VP8Proba* proba) { assert(br != NULL); assert(hdr != NULL); hdr->use_segment_ = VP8Get(br); if (hdr->use_segment_) { hdr->update_map_ = VP8Get(br); if (VP8Get(br)) { // update data int s; hdr->absolute_delta_ = VP8Get(br); for (s = 0; s < NUM_MB_SEGMENTS; ++s) { hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; } for (s = 0; s < NUM_MB_SEGMENTS; ++s) { hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; } } if (hdr->update_map_) { int s; for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u; } } } else { hdr->update_map_ = 0; } return !br->eof_; } // Paragraph 9.5 // This function returns VP8_STATUS_SUSPENDED if we don't have all the // necessary data in 'buf'. // This case is not necessarily an error (for incremental decoding). // Still, no bitreader is ever initialized to make it possible to read // unavailable memory. // If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA // is returned, and this is an unrecoverable error. // If the partitions were positioned ok, VP8_STATUS_OK is returned. static VP8StatusCode ParsePartitions(VP8Decoder* const dec, const uint8_t* buf, size_t size) { VP8BitReader* const br = &dec->br_; const uint8_t* sz = buf; const uint8_t* buf_end = buf + size; const uint8_t* part_start; int last_part; int p; dec->num_parts_ = 1 << VP8GetValue(br, 2); last_part = dec->num_parts_ - 1; part_start = buf + last_part * 3; if (buf_end < part_start) { // we can't even read the sizes with sz[]! That's a failure. return VP8_STATUS_NOT_ENOUGH_DATA; } for (p = 0; p < last_part; ++p) { const uint32_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); const uint8_t* part_end = part_start + psize; if (part_end > buf_end) part_end = buf_end; VP8InitBitReader(dec->parts_ + p, part_start, part_end); part_start = part_end; sz += 3; } VP8InitBitReader(dec->parts_ + last_part, part_start, buf_end); return (part_start < buf_end) ? VP8_STATUS_OK : VP8_STATUS_SUSPENDED; // Init is ok, but there's not enough data } // Paragraph 9.4 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { VP8FilterHeader* const hdr = &dec->filter_hdr_; hdr->simple_ = VP8Get(br); hdr->level_ = VP8GetValue(br, 6); hdr->sharpness_ = VP8GetValue(br, 3); hdr->use_lf_delta_ = VP8Get(br); if (hdr->use_lf_delta_) { if (VP8Get(br)) { // update lf-delta? int i; for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { if (VP8Get(br)) { hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6); } } for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { if (VP8Get(br)) { hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6); } } } } dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2; return !br->eof_; } // Topmost call int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { const uint8_t* buf; size_t buf_size; VP8FrameHeader* frm_hdr; VP8PictureHeader* pic_hdr; VP8BitReader* br; VP8StatusCode status; if (dec == NULL) { return 0; } SetOk(dec); if (io == NULL) { return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, "null VP8Io passed to VP8GetHeaders()"); } buf = io->data; buf_size = io->data_size; if (buf_size < 4) { return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, "Truncated header."); } // Paragraph 9.1 { const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); frm_hdr = &dec->frm_hdr_; frm_hdr->key_frame_ = !(bits & 1); frm_hdr->profile_ = (bits >> 1) & 7; frm_hdr->show_ = (bits >> 4) & 1; frm_hdr->partition_length_ = (bits >> 5); if (frm_hdr->profile_ > 3) return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "Incorrect keyframe parameters."); if (!frm_hdr->show_) return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, "Frame not displayable."); buf += 3; buf_size -= 3; } pic_hdr = &dec->pic_hdr_; if (frm_hdr->key_frame_) { // Paragraph 9.2 if (buf_size < 7) { return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, "cannot parse picture header"); } if (!VP8CheckSignature(buf, buf_size)) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "Bad code word"); } pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff; pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2 pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff; pic_hdr->yscale_ = buf[6] >> 6; buf += 7; buf_size -= 7; dec->mb_w_ = (pic_hdr->width_ + 15) >> 4; dec->mb_h_ = (pic_hdr->height_ + 15) >> 4; // Setup default output area (can be later modified during io->setup()) io->width = pic_hdr->width_; io->height = pic_hdr->height_; io->use_scaling = 0; io->use_cropping = 0; io->crop_top = 0; io->crop_left = 0; io->crop_right = io->width; io->crop_bottom = io->height; io->mb_w = io->width; // sanity check io->mb_h = io->height; // ditto VP8ResetProba(&dec->proba_); ResetSegmentHeader(&dec->segment_hdr_); dec->segment_ = 0; // default for intra } // Check if we have all the partition #0 available, and initialize dec->br_ // to read this partition (and this partition only). if (frm_hdr->partition_length_ > buf_size) { return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, "bad partition length"); } br = &dec->br_; VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_); buf += frm_hdr->partition_length_; buf_size -= frm_hdr->partition_length_; if (frm_hdr->key_frame_) { pic_hdr->colorspace_ = VP8Get(br); pic_hdr->clamp_type_ = VP8Get(br); } if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "cannot parse segment header"); } // Filter specs if (!ParseFilterHeader(br, dec)) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "cannot parse filter header"); } status = ParsePartitions(dec, buf, buf_size); if (status != VP8_STATUS_OK) { return VP8SetError(dec, status, "cannot parse partitions"); } // quantizer change VP8ParseQuant(dec); // Frame buffer marking if (!frm_hdr->key_frame_) { return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, "Not a key frame."); } VP8Get(br); // ignore the value of update_proba_ VP8ParseProba(br, dec); #ifdef WEBP_EXPERIMENTAL_FEATURES // Extensions if (dec->pic_hdr_.colorspace_) { const size_t kTrailerSize = 8; const uint8_t kTrailerMarker = 0x01; const uint8_t* ext_buf = buf - kTrailerSize; size_t size; if (frm_hdr->partition_length_ < kTrailerSize || ext_buf[kTrailerSize - 1] != kTrailerMarker) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "RIFF: Inconsistent extra information."); } // Layer size = (ext_buf[0] << 0) | (ext_buf[1] << 8) | (ext_buf[2] << 16); dec->layer_data_size_ = size; dec->layer_data_ = NULL; // will be set later dec->layer_colorspace_ = ext_buf[3]; } #endif // sanitized state dec->ready_ = 1; return 1; } //------------------------------------------------------------------------------ // Residual decoding (Paragraph 13.2 / 13.3) static const int kBands[16 + 1] = { 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0 // extra entry as sentinel }; static const uint8_t kCat3[] = { 173, 148, 140, 0 }; static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; static const uint8_t kCat6[] = { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { int v; if (!VP8GetBit(br, p[3])) { if (!VP8GetBit(br, p[4])) { v = 2; } else { v = 3 + VP8GetBit(br, p[5]); } } else { if (!VP8GetBit(br, p[6])) { if (!VP8GetBit(br, p[7])) { v = 5 + VP8GetBit(br, 159); } else { v = 7 + 2 * VP8GetBit(br, 165); v += VP8GetBit(br, 145); } } else { const uint8_t* tab; const int bit1 = VP8GetBit(br, p[8]); const int bit0 = VP8GetBit(br, p[9 + bit1]); const int cat = 2 * bit1 + bit0; v = 0; for (tab = kCat3456[cat]; *tab; ++tab) { v += v + VP8GetBit(br, *tab); } v += 3 + (8 << cat); } } return v; } // Returns the position of the last non-zero coeff plus one static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob, int ctx, const quant_t dq, int n, int16_t* out) { // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'. const uint8_t* p = prob[n].probas_[ctx]; for (; n < 16; ++n) { if (!VP8GetBit(br, p[0])) { return n; // previous coeff was last non-zero coeff } while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs p = prob[kBands[++n]].probas_[0]; if (n == 16) return 16; } { // non zero coeff const VP8ProbaArray* const p_ctx = &prob[kBands[n + 1]].probas_[0]; int v; if (!VP8GetBit(br, p[2])) { v = 1; p = p_ctx[1]; } else { v = GetLargeValue(br, p); p = p_ctx[2]; } out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; } } return 16; } static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) { nz_coeffs <<= 2; nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz; return nz_coeffs; } static int ParseResiduals(VP8Decoder* const dec, VP8MB* const mb, VP8BitReader* const token_br) { VP8BandProbas (* const bands)[NUM_BANDS] = dec->proba_.bands_; const VP8BandProbas* ac_proba; const VP8QuantMatrix* const q = &dec->dqm_[dec->segment_]; VP8MBData* const block = dec->mb_data_ + dec->mb_x_; int16_t* dst = block->coeffs_; VP8MB* const left_mb = dec->mb_info_ - 1; uint8_t tnz, lnz; uint32_t non_zero_y = 0; uint32_t non_zero_uv = 0; int x, y, ch; uint32_t out_t_nz, out_l_nz; int first; memset(dst, 0, 384 * sizeof(*dst)); if (!block->is_i4x4_) { // parse DC int16_t dc[16] = { 0 }; const int ctx = mb->nz_dc_ + left_mb->nz_dc_; const int nz = GetCoeffs(token_br, bands[1], ctx, q->y2_mat_, 0, dc); mb->nz_dc_ = left_mb->nz_dc_ = (nz > 0); if (nz > 1) { // more than just the DC -> perform the full transform VP8TransformWHT(dc, dst); } else { // only DC is non-zero -> inlined simplified transform int i; const int dc0 = (dc[0] + 3) >> 3; for (i = 0; i < 16 * 16; i += 16) dst[i] = dc0; } first = 1; ac_proba = bands[0]; } else { first = 0; ac_proba = bands[3]; } tnz = mb->nz_ & 0x0f; lnz = left_mb->nz_ & 0x0f; for (y = 0; y < 4; ++y) { int l = lnz & 1; uint32_t nz_coeffs = 0; for (x = 0; x < 4; ++x) { const int ctx = l + (tnz & 1); const int nz = GetCoeffs(token_br, ac_proba, ctx, q->y1_mat_, first, dst); l = (nz > first); tnz = (tnz >> 1) | (l << 7); nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0); dst += 16; } tnz >>= 4; lnz = (lnz >> 1) | (l << 7); non_zero_y = (non_zero_y << 8) | nz_coeffs; } out_t_nz = tnz; out_l_nz = lnz >> 4; for (ch = 0; ch < 4; ch += 2) { uint32_t nz_coeffs = 0; tnz = mb->nz_ >> (4 + ch); lnz = left_mb->nz_ >> (4 + ch); for (y = 0; y < 2; ++y) { int l = lnz & 1; for (x = 0; x < 2; ++x) { const int ctx = l + (tnz & 1); const int nz = GetCoeffs(token_br, bands[2], ctx, q->uv_mat_, 0, dst); l = (nz > 0); tnz = (tnz >> 1) | (l << 3); nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0); dst += 16; } tnz >>= 2; lnz = (lnz >> 1) | (l << 5); } // Note: we don't really need the per-4x4 details for U/V blocks. non_zero_uv |= nz_coeffs << (4 * ch); out_t_nz |= (tnz << 4) << ch; out_l_nz |= (lnz & 0xf0) << ch; } mb->nz_ = out_t_nz; left_mb->nz_ = out_l_nz; block->non_zero_y_ = non_zero_y; block->non_zero_uv_ = non_zero_uv; // We look at the mode-code of each block and check if some blocks have less // than three non-zero coeffs (code < 2). This is to avoid dithering flat and // empty blocks. block->dither_ = (non_zero_uv & 0xaaaa) ? 0 : q->dither_; return !(non_zero_y | non_zero_uv); // will be used for further optimization } //------------------------------------------------------------------------------ // Main loop int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) { VP8BitReader* const br = &dec->br_; VP8MB* const left = dec->mb_info_ - 1; VP8MB* const mb = dec->mb_info_ + dec->mb_x_; VP8MBData* const block = dec->mb_data_ + dec->mb_x_; int skip; // Note: we don't save segment map (yet), as we don't expect // to decode more than 1 keyframe. if (dec->segment_hdr_.update_map_) { // Hardcoded tree parsing dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ? VP8GetBit(br, dec->proba_.segments_[1]) : 2 + VP8GetBit(br, dec->proba_.segments_[2]); } skip = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0; VP8ParseIntraMode(br, dec); if (br->eof_) { return 0; } if (!skip) { skip = ParseResiduals(dec, mb, token_br); } else { left->nz_ = mb->nz_ = 0; if (!block->is_i4x4_) { left->nz_dc_ = mb->nz_dc_ = 0; } block->non_zero_y_ = 0; block->non_zero_uv_ = 0; } if (dec->filter_type_ > 0) { // store filter info VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_; *finfo = dec->fstrengths_[dec->segment_][block->is_i4x4_]; finfo->f_inner_ |= !skip; } return !token_br->eof_; } void VP8InitScanline(VP8Decoder* const dec) { VP8MB* const left = dec->mb_info_ - 1; left->nz_ = 0; left->nz_dc_ = 0; memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); dec->mb_x_ = 0; } static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) { // Parse bitstream for this row. VP8BitReader* const token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) { if (!VP8DecodeMB(dec, token_br)) { return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, "Premature end-of-file encountered."); } } VP8InitScanline(dec); // Prepare for next scanline // Reconstruct, filter and emit the row. if (!VP8ProcessRow(dec, io)) { return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted."); } } if (dec->mt_method_ > 0) { if (!WebPWorkerSync(&dec->worker_)) return 0; } // Finish #ifdef WEBP_EXPERIMENTAL_FEATURES if (dec->layer_data_size_ > 0) { if (!VP8DecodeLayer(dec)) { return 0; } } #endif return 1; } // Main entry point int VP8Decode(VP8Decoder* const dec, VP8Io* const io) { int ok = 0; if (dec == NULL) { return 0; } if (io == NULL) { return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, "NULL VP8Io parameter in VP8Decode()."); } if (!dec->ready_) { if (!VP8GetHeaders(dec, io)) { return 0; } } assert(dec->ready_); // Finish setting up the decoding parameter. Will call io->setup(). ok = (VP8EnterCritical(dec, io) == VP8_STATUS_OK); if (ok) { // good to go. // Will allocate memory and prepare everything. if (ok) ok = VP8InitFrame(dec, io); // Main decoding loop if (ok) ok = ParseFrame(dec, io); // Exit. ok &= VP8ExitCritical(dec, io); } if (!ok) { VP8Clear(dec); return 0; } dec->ready_ = 0; return ok; } void VP8Clear(VP8Decoder* const dec) { if (dec == NULL) { return; } if (dec->mt_method_ > 0) { WebPWorkerEnd(&dec->worker_); } ALPHDelete(dec->alph_dec_); dec->alph_dec_ = NULL; free(dec->mem_); dec->mem_ = NULL; dec->mem_size_ = 0; memset(&dec->br_, 0, sizeof(dec->br_)); dec->ready_ = 0; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dec/layer.c0000644000014400001440000000153612255002107012650 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Enhancement layer (for YUV444/422) // // Author: Skal (pascal.massimino@gmail.com) #include #include #include "./vp8i.h" //------------------------------------------------------------------------------ int VP8DecodeLayer(VP8Decoder* const dec) { assert(dec); assert(dec->layer_data_size_ > 0); (void)dec; // TODO: handle enhancement layer here. return 1; } libwebp-0.4.0/src/dec/Makefile.am0000644000014400001440000000170312255002107013420 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebpdecode.la libwebpdecode_la_SOURCES = libwebpdecode_la_SOURCES += alpha.c libwebpdecode_la_SOURCES += alphai.h libwebpdecode_la_SOURCES += buffer.c libwebpdecode_la_SOURCES += decode_vp8.h libwebpdecode_la_SOURCES += frame.c libwebpdecode_la_SOURCES += idec.c libwebpdecode_la_SOURCES += io.c libwebpdecode_la_SOURCES += layer.c libwebpdecode_la_SOURCES += quant.c libwebpdecode_la_SOURCES += tree.c libwebpdecode_la_SOURCES += vp8.c libwebpdecode_la_SOURCES += vp8i.h libwebpdecode_la_SOURCES += vp8l.c libwebpdecode_la_SOURCES += vp8li.h libwebpdecode_la_SOURCES += webp.c libwebpdecode_la_SOURCES += webpi.h libwebpdecodeinclude_HEADERS = libwebpdecodeinclude_HEADERS += ../webp/decode.h libwebpdecodeinclude_HEADERS += ../webp/types.h noinst_HEADERS = noinst_HEADERS += ../webp/format_constants.h libwebpdecode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) libwebpdecodeincludedir = $(includedir)/webp libwebp-0.4.0/src/utils/0000755000014400001440000000000012255206714012002 5ustar libwebp-0.4.0/src/utils/bit_writer.c0000644000014400001440000002123212255002107014306 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Bit writing and boolean coder // // Author: Skal (pascal.massimino@gmail.com) // Vikas Arora (vikaas.arora@gmail.com) #include #include // for memcpy() #include #include "./bit_writer.h" //------------------------------------------------------------------------------ // VP8BitWriter static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) { uint8_t* new_buf; size_t new_size; const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size; const size_t needed_size = (size_t)needed_size_64b; if (needed_size_64b != needed_size) { bw->error_ = 1; return 0; } if (needed_size <= bw->max_pos_) return 1; // If the following line wraps over 32bit, the test just after will catch it. new_size = 2 * bw->max_pos_; if (new_size < needed_size) new_size = needed_size; if (new_size < 1024) new_size = 1024; new_buf = (uint8_t*)malloc(new_size); if (new_buf == NULL) { bw->error_ = 1; return 0; } if (bw->pos_ > 0) { assert(bw->buf_ != NULL); memcpy(new_buf, bw->buf_, bw->pos_); } free(bw->buf_); bw->buf_ = new_buf; bw->max_pos_ = new_size; return 1; } static void kFlush(VP8BitWriter* const bw) { const int s = 8 + bw->nb_bits_; const int32_t bits = bw->value_ >> s; assert(bw->nb_bits_ >= 0); bw->value_ -= bits << s; bw->nb_bits_ -= 8; if ((bits & 0xff) != 0xff) { size_t pos = bw->pos_; if (!BitWriterResize(bw, bw->run_ + 1)) { return; } if (bits & 0x100) { // overflow -> propagate carry over pending 0xff's if (pos > 0) bw->buf_[pos - 1]++; } if (bw->run_ > 0) { const int value = (bits & 0x100) ? 0x00 : 0xff; for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value; } bw->buf_[pos++] = bits; bw->pos_ = pos; } else { bw->run_++; // delay writing of bytes 0xff, pending eventual carry. } } //------------------------------------------------------------------------------ // renormalization static const uint8_t kNorm[128] = { // renorm_sizes[i] = 8 - log2(i) 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }; // range = ((range + 1) << kVP8Log2Range[range]) - 1 static const uint8_t kNewRange[128] = { 127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239, 127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239, 247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 127 }; int VP8PutBit(VP8BitWriter* const bw, int bit, int prob) { const int split = (bw->range_ * prob) >> 8; if (bit) { bw->value_ += split + 1; bw->range_ -= split + 1; } else { bw->range_ = split; } if (bw->range_ < 127) { // emit 'shift' bits out and renormalize const int shift = kNorm[bw->range_]; bw->range_ = kNewRange[bw->range_]; bw->value_ <<= shift; bw->nb_bits_ += shift; if (bw->nb_bits_ > 0) kFlush(bw); } return bit; } int VP8PutBitUniform(VP8BitWriter* const bw, int bit) { const int split = bw->range_ >> 1; if (bit) { bw->value_ += split + 1; bw->range_ -= split + 1; } else { bw->range_ = split; } if (bw->range_ < 127) { bw->range_ = kNewRange[bw->range_]; bw->value_ <<= 1; bw->nb_bits_ += 1; if (bw->nb_bits_ > 0) kFlush(bw); } return bit; } void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) { int mask; for (mask = 1 << (nb_bits - 1); mask; mask >>= 1) VP8PutBitUniform(bw, value & mask); } void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) { if (!VP8PutBitUniform(bw, value != 0)) return; if (value < 0) { VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1); } else { VP8PutValue(bw, value << 1, nb_bits + 1); } } //------------------------------------------------------------------------------ int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) { bw->range_ = 255 - 1; bw->value_ = 0; bw->run_ = 0; bw->nb_bits_ = -8; bw->pos_ = 0; bw->max_pos_ = 0; bw->error_ = 0; bw->buf_ = NULL; return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1; } uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) { VP8PutValue(bw, 0, 9 - bw->nb_bits_); bw->nb_bits_ = 0; // pad with zeroes kFlush(bw); return bw->buf_; } int VP8BitWriterAppend(VP8BitWriter* const bw, const uint8_t* data, size_t size) { assert(data); if (bw->nb_bits_ != -8) return 0; // kFlush() must have been called if (!BitWriterResize(bw, size)) return 0; memcpy(bw->buf_ + bw->pos_, data, size); bw->pos_ += size; return 1; } void VP8BitWriterWipeOut(VP8BitWriter* const bw) { if (bw) { free(bw->buf_); memset(bw, 0, sizeof(*bw)); } } //------------------------------------------------------------------------------ // VP8LBitWriter // Returns 1 on success. static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) { uint8_t* allocated_buf; size_t allocated_size; const size_t current_size = VP8LBitWriterNumBytes(bw); const uint64_t size_required_64b = (uint64_t)current_size + extra_size; const size_t size_required = (size_t)size_required_64b; if (size_required != size_required_64b) { bw->error_ = 1; return 0; } if (bw->max_bytes_ > 0 && size_required <= bw->max_bytes_) return 1; allocated_size = (3 * bw->max_bytes_) >> 1; if (allocated_size < size_required) allocated_size = size_required; // make allocated size multiple of 1k allocated_size = (((allocated_size >> 10) + 1) << 10); allocated_buf = (uint8_t*)malloc(allocated_size); if (allocated_buf == NULL) { bw->error_ = 1; return 0; } memcpy(allocated_buf, bw->buf_, current_size); free(bw->buf_); bw->buf_ = allocated_buf; bw->max_bytes_ = allocated_size; memset(allocated_buf + current_size, 0, allocated_size - current_size); return 1; } int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) { memset(bw, 0, sizeof(*bw)); return VP8LBitWriterResize(bw, expected_size); } void VP8LBitWriterDestroy(VP8LBitWriter* const bw) { if (bw != NULL) { free(bw->buf_); memset(bw, 0, sizeof(*bw)); } } void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) { if (n_bits < 1) return; #if !defined(__BIG_ENDIAN__) // Technically, this branch of the code can write up to 25 bits at a time, // but in prefix encoding, the maximum number of bits written is 18 at a time. { uint8_t* const p = &bw->buf_[bw->bit_pos_ >> 3]; uint32_t v = *(const uint32_t*)p; v |= bits << (bw->bit_pos_ & 7); *(uint32_t*)p = v; bw->bit_pos_ += n_bits; } #else // BIG_ENDIAN { uint8_t* p = &bw->buf_[bw->bit_pos_ >> 3]; const int bits_reserved_in_first_byte = bw->bit_pos_ & 7; const int bits_left_to_write = n_bits - 8 + bits_reserved_in_first_byte; // implicit & 0xff is assumed for uint8_t arithmetic *p++ |= bits << bits_reserved_in_first_byte; bits >>= 8 - bits_reserved_in_first_byte; if (bits_left_to_write >= 1) { *p++ = bits; bits >>= 8; if (bits_left_to_write >= 9) { *p++ = bits; bits >>= 8; } } assert(n_bits <= 25); *p = bits; bw->bit_pos_ += n_bits; } #endif if ((bw->bit_pos_ >> 3) > (bw->max_bytes_ - 8)) { const uint64_t extra_size = 32768ULL + bw->max_bytes_; if (extra_size != (size_t)extra_size || !VP8LBitWriterResize(bw, (size_t)extra_size)) { bw->bit_pos_ = 0; bw->error_ = 1; } } } //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/alpha_processing.h0000644000014400001440000000313112255002107015460 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utilities for processing transparent channel. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_UTILS_ALPHA_PROCESSING_H_ #define WEBP_UTILS_ALPHA_PROCESSING_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B). // Un-Multiply operation transforms x into x * 255 / A. // Pre-Multiply or Un-Multiply (if 'inverse' is true) argb values in a row. void WebPMultARGBRow(uint32_t* const ptr, int width, int inverse); // Same a WebPMultARGBRow(), but for several rows. void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, int inverse); // Same for a row of single values, with side alpha values. void WebPMultRow(uint8_t* const ptr, const uint8_t* const alpha, int width, int inverse); // Same a WebPMultRow(), but for several 'num_rows' rows. void WebPMultRows(uint8_t* ptr, int stride, const uint8_t* alpha, int alpha_stride, int width, int num_rows, int inverse); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_UTILS_ALPHA_PROCESSING_H_ libwebp-0.4.0/src/utils/Makefile.in0000644000014400001440000005073012255206714014054 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ @BUILD_LIBWEBPDECODER_TRUE@am__append_1 = libwebputilsdecode.la subdir = src/utils DIST_COMMON = $(common_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libwebputils_la_LIBADD = am__objects_1 = alpha_processing.lo bit_reader.lo color_cache.lo \ filters.lo huffman.lo quant_levels_dec.lo rescaler.lo \ random.lo thread.lo utils.lo am__objects_2 = bit_writer.lo huffman_encode.lo quant_levels.lo am_libwebputils_la_OBJECTS = $(am__objects_1) $(am__objects_2) libwebputils_la_OBJECTS = $(am_libwebputils_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libwebputilsdecode_la_LIBADD = am__libwebputilsdecode_la_SOURCES_DIST = alpha_processing.c \ alpha_processing.h bit_reader.c bit_reader.h color_cache.c \ color_cache.h filters.c filters.h huffman.c huffman.h \ quant_levels_dec.c quant_levels_dec.h rescaler.c rescaler.h \ random.c random.h thread.c thread.h utils.c utils.h @BUILD_LIBWEBPDECODER_TRUE@am_libwebputilsdecode_la_OBJECTS = \ @BUILD_LIBWEBPDECODER_TRUE@ $(am__objects_1) libwebputilsdecode_la_OBJECTS = $(am_libwebputilsdecode_la_OBJECTS) @BUILD_LIBWEBPDECODER_TRUE@am_libwebputilsdecode_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebputils_la_SOURCES) $(libwebputilsdecode_la_SOURCES) DIST_SOURCES = $(libwebputils_la_SOURCES) \ $(am__libwebputilsdecode_la_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(commondir)" HEADERS = $(common_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebputils.la $(am__append_1) common_HEADERS = ../webp/types.h commondir = $(includedir)/webp COMMON_SOURCES = alpha_processing.c alpha_processing.h bit_reader.c \ bit_reader.h color_cache.c color_cache.h filters.c filters.h \ huffman.c huffman.h quant_levels_dec.c quant_levels_dec.h \ rescaler.c rescaler.h random.c random.h thread.c thread.h \ utils.c utils.h ENC_SOURCES = bit_writer.c bit_writer.h huffman_encode.c \ huffman_encode.h quant_levels.c quant_levels.h libwebputils_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) @BUILD_LIBWEBPDECODER_TRUE@libwebputilsdecode_la_SOURCES = $(COMMON_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/utils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/utils/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebputils.la: $(libwebputils_la_OBJECTS) $(libwebputils_la_DEPENDENCIES) $(EXTRA_libwebputils_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libwebputils_la_OBJECTS) $(libwebputils_la_LIBADD) $(LIBS) libwebputilsdecode.la: $(libwebputilsdecode_la_OBJECTS) $(libwebputilsdecode_la_DEPENDENCIES) $(EXTRA_libwebputilsdecode_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(am_libwebputilsdecode_la_rpath) $(libwebputilsdecode_la_OBJECTS) $(libwebputilsdecode_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha_processing.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit_reader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit_writer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color_cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filters.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman_encode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quant_levels.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quant_levels_dec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rescaler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 install-commonHEADERS: $(common_HEADERS) @$(NORMAL_INSTALL) test -z "$(commondir)" || $(MKDIR_P) "$(DESTDIR)$(commondir)" @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(commondir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(commondir)" || exit $$?; \ done uninstall-commonHEADERS: @$(NORMAL_UNINSTALL) @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(commondir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(commondir)"; 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-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-commonHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: 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 -rf ./$(DEPDIR) -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-commonHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-commonHEADERS 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-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 uninstall uninstall-am uninstall-commonHEADERS # 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: libwebp-0.4.0/src/utils/huffman.h0000644000014400001440000000613212255002107013567 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utilities for building and looking up Huffman trees. // // Author: Urvang Joshi (urvang@google.com) #ifndef WEBP_UTILS_HUFFMAN_H_ #define WEBP_UTILS_HUFFMAN_H_ #include #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // A node of a Huffman tree. typedef struct { int symbol_; int children_; // delta offset to both children (contiguous) or 0 if leaf. } HuffmanTreeNode; // Huffman Tree. #define HUFF_LUT_BITS 7 #define HUFF_LUT (1U << HUFF_LUT_BITS) typedef struct HuffmanTree HuffmanTree; struct HuffmanTree { // Fast lookup for short bit lengths. uint8_t lut_bits_[HUFF_LUT]; int16_t lut_symbol_[HUFF_LUT]; int16_t lut_jump_[HUFF_LUT]; // Complete tree for lookups. HuffmanTreeNode* root_; // all the nodes, starting at root. int max_nodes_; // max number of nodes int num_nodes_; // number of currently occupied nodes }; // Returns true if the given node is not a leaf of the Huffman tree. static WEBP_INLINE int HuffmanTreeNodeIsNotLeaf( const HuffmanTreeNode* const node) { return node->children_; } // Go down one level. Most critical function. 'right_child' must be 0 or 1. static WEBP_INLINE const HuffmanTreeNode* HuffmanTreeNextNode( const HuffmanTreeNode* node, int right_child) { return node + node->children_ + right_child; } // Releases the nodes of the Huffman tree. // Note: It does NOT free 'tree' itself. void HuffmanTreeRelease(HuffmanTree* const tree); // Builds Huffman tree assuming code lengths are implicitly in symbol order. // Returns false in case of error (invalid tree or memory error). int HuffmanTreeBuildImplicit(HuffmanTree* const tree, const int* const code_lengths, int code_lengths_size); // Build a Huffman tree with explicitly given lists of code lengths, codes // and symbols. Verifies that all symbols added are smaller than max_symbol. // Returns false in case of an invalid symbol, invalid tree or memory error. int HuffmanTreeBuildExplicit(HuffmanTree* const tree, const int* const code_lengths, const int* const codes, const int* const symbols, int max_symbol, int num_symbols); // Utility: converts Huffman code lengths to corresponding Huffman codes. // 'huff_codes' should be pre-allocated. // Returns false in case of error (memory allocation, invalid codes). int HuffmanCodeLengthsToCodes(const int* const code_lengths, int code_lengths_size, int* const huff_codes); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_UTILS_HUFFMAN_H_ libwebp-0.4.0/src/utils/thread.c0000644000014400001440000001634212255002107013411 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Multi-threaded worker // // Author: Skal (pascal.massimino@gmail.com) #include #include // for memset() #include "./thread.h" #ifdef WEBP_USE_THREAD #if defined(_WIN32) //------------------------------------------------------------------------------ // simplistic pthread emulation layer #include // _beginthreadex requires __stdcall #define THREADFN unsigned int __stdcall #define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val) static int pthread_create(pthread_t* const thread, const void* attr, unsigned int (__stdcall *start)(void*), void* arg) { (void)attr; *thread = (pthread_t)_beginthreadex(NULL, /* void *security */ 0, /* unsigned stack_size */ start, arg, 0, /* unsigned initflag */ NULL); /* unsigned *thrdaddr */ if (*thread == NULL) return 1; SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); return 0; } static int pthread_join(pthread_t thread, void** value_ptr) { (void)value_ptr; return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 || CloseHandle(thread) == 0); } // Mutex static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) { (void)mutexattr; InitializeCriticalSection(mutex); return 0; } static int pthread_mutex_lock(pthread_mutex_t* const mutex) { EnterCriticalSection(mutex); return 0; } static int pthread_mutex_unlock(pthread_mutex_t* const mutex) { LeaveCriticalSection(mutex); return 0; } static int pthread_mutex_destroy(pthread_mutex_t* const mutex) { DeleteCriticalSection(mutex); return 0; } // Condition static int pthread_cond_destroy(pthread_cond_t* const condition) { int ok = 1; ok &= (CloseHandle(condition->waiting_sem_) != 0); ok &= (CloseHandle(condition->received_sem_) != 0); ok &= (CloseHandle(condition->signal_event_) != 0); return !ok; } static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) { (void)cond_attr; condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL); condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL); condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL); if (condition->waiting_sem_ == NULL || condition->received_sem_ == NULL || condition->signal_event_ == NULL) { pthread_cond_destroy(condition); return 1; } return 0; } static int pthread_cond_signal(pthread_cond_t* const condition) { int ok = 1; if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) { // a thread is waiting in pthread_cond_wait: allow it to be notified ok = SetEvent(condition->signal_event_); // wait until the event is consumed so the signaler cannot consume // the event via its own pthread_cond_wait. ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) != WAIT_OBJECT_0); } return !ok; } static int pthread_cond_wait(pthread_cond_t* const condition, pthread_mutex_t* const mutex) { int ok; // note that there is a consumer available so the signal isn't dropped in // pthread_cond_signal if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) return 1; // now unlock the mutex so pthread_cond_signal may be issued pthread_mutex_unlock(mutex); ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == WAIT_OBJECT_0); ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); pthread_mutex_lock(mutex); return !ok; } #else // !_WIN32 # define THREADFN void* # define THREAD_RETURN(val) val #endif // _WIN32 //------------------------------------------------------------------------------ static THREADFN ThreadLoop(void* ptr) { WebPWorker* const worker = (WebPWorker*)ptr; int done = 0; while (!done) { pthread_mutex_lock(&worker->mutex_); while (worker->status_ == OK) { // wait in idling mode pthread_cond_wait(&worker->condition_, &worker->mutex_); } if (worker->status_ == WORK) { WebPWorkerExecute(worker); worker->status_ = OK; } else if (worker->status_ == NOT_OK) { // finish the worker done = 1; } // signal to the main thread that we're done (for Sync()) pthread_cond_signal(&worker->condition_); pthread_mutex_unlock(&worker->mutex_); } return THREAD_RETURN(NULL); // Thread is finished } // main thread state control static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) { // no-op when attempting to change state on a thread that didn't come up if (worker->status_ < OK) return; pthread_mutex_lock(&worker->mutex_); // wait for the worker to finish while (worker->status_ != OK) { pthread_cond_wait(&worker->condition_, &worker->mutex_); } // assign new status and release the working thread if needed if (new_status != OK) { worker->status_ = new_status; pthread_cond_signal(&worker->condition_); } pthread_mutex_unlock(&worker->mutex_); } #endif // WEBP_USE_THREAD //------------------------------------------------------------------------------ void WebPWorkerInit(WebPWorker* const worker) { memset(worker, 0, sizeof(*worker)); worker->status_ = NOT_OK; } int WebPWorkerSync(WebPWorker* const worker) { #ifdef WEBP_USE_THREAD ChangeState(worker, OK); #endif assert(worker->status_ <= OK); return !worker->had_error; } int WebPWorkerReset(WebPWorker* const worker) { int ok = 1; worker->had_error = 0; if (worker->status_ < OK) { #ifdef WEBP_USE_THREAD if (pthread_mutex_init(&worker->mutex_, NULL) || pthread_cond_init(&worker->condition_, NULL)) { return 0; } pthread_mutex_lock(&worker->mutex_); ok = !pthread_create(&worker->thread_, NULL, ThreadLoop, worker); if (ok) worker->status_ = OK; pthread_mutex_unlock(&worker->mutex_); #else worker->status_ = OK; #endif } else if (worker->status_ > OK) { ok = WebPWorkerSync(worker); } assert(!ok || (worker->status_ == OK)); return ok; } void WebPWorkerExecute(WebPWorker* const worker) { if (worker->hook != NULL) { worker->had_error |= !worker->hook(worker->data1, worker->data2); } } void WebPWorkerLaunch(WebPWorker* const worker) { #ifdef WEBP_USE_THREAD ChangeState(worker, WORK); #else WebPWorkerExecute(worker); #endif } void WebPWorkerEnd(WebPWorker* const worker) { if (worker->status_ >= OK) { #ifdef WEBP_USE_THREAD ChangeState(worker, NOT_OK); pthread_join(worker->thread_, NULL); pthread_mutex_destroy(&worker->mutex_); pthread_cond_destroy(&worker->condition_); #else worker->status_ = NOT_OK; #endif } assert(worker->status_ == NOT_OK); } //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/huffman_encode.c0000644000014400001440000003311412255002107015077 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) // // Entropy encoding (Huffman) for webp lossless. #include #include #include #include "./huffman_encode.h" #include "../utils/utils.h" #include "../webp/format_constants.h" // ----------------------------------------------------------------------------- // Util function to optimize the symbol map for RLE coding // Heuristics for selecting the stride ranges to collapse. static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) { return abs(a - b) < 4; } // Change the population counts in a way that the consequent // Huffman tree compression, especially its RLE-part, give smaller output. static int OptimizeHuffmanForRle(int length, int* const counts) { uint8_t* good_for_rle; // 1) Let's make the Huffman code more compatible with rle encoding. int i; for (; length >= 0; --length) { if (length == 0) { return 1; // All zeros. } if (counts[length - 1] != 0) { // Now counts[0..length - 1] does not have trailing zeros. break; } } // 2) Let's mark all population counts that already can be encoded // with an rle code. good_for_rle = (uint8_t*)calloc(length, 1); if (good_for_rle == NULL) { return 0; } { // Let's not spoil any of the existing good rle codes. // Mark any seq of 0's that is longer as 5 as a good_for_rle. // Mark any seq of non-0's that is longer as 7 as a good_for_rle. int symbol = counts[0]; int stride = 0; for (i = 0; i < length + 1; ++i) { if (i == length || counts[i] != symbol) { if ((symbol == 0 && stride >= 5) || (symbol != 0 && stride >= 7)) { int k; for (k = 0; k < stride; ++k) { good_for_rle[i - k - 1] = 1; } } stride = 1; if (i != length) { symbol = counts[i]; } } else { ++stride; } } } // 3) Let's replace those population counts that lead to more rle codes. { int stride = 0; int limit = counts[0]; int sum = 0; for (i = 0; i < length + 1; ++i) { if (i == length || good_for_rle[i] || (i != 0 && good_for_rle[i - 1]) || !ValuesShouldBeCollapsedToStrideAverage(counts[i], limit)) { if (stride >= 4 || (stride >= 3 && sum == 0)) { int k; // The stride must end, collapse what we have, if we have enough (4). int count = (sum + stride / 2) / stride; if (count < 1) { count = 1; } if (sum == 0) { // Don't make an all zeros stride to be upgraded to ones. count = 0; } for (k = 0; k < stride; ++k) { // We don't want to change value at counts[i], // that is already belonging to the next stride. Thus - 1. counts[i - k - 1] = count; } } stride = 0; sum = 0; if (i < length - 3) { // All interesting strides have a count of at least 4, // at least when non-zeros. limit = (counts[i] + counts[i + 1] + counts[i + 2] + counts[i + 3] + 2) / 4; } else if (i < length) { limit = counts[i]; } else { limit = 0; } } ++stride; if (i != length) { sum += counts[i]; if (stride >= 4) { limit = (sum + stride / 2) / stride; } } } } free(good_for_rle); return 1; } typedef struct { int total_count_; int value_; int pool_index_left_; int pool_index_right_; } HuffmanTree; // A comparer function for two Huffman trees: sorts first by 'total count' // (more comes first), and then by 'value' (more comes first). static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) { const HuffmanTree* const t1 = (const HuffmanTree*)ptr1; const HuffmanTree* const t2 = (const HuffmanTree*)ptr2; if (t1->total_count_ > t2->total_count_) { return -1; } else if (t1->total_count_ < t2->total_count_) { return 1; } else { assert(t1->value_ != t2->value_); return (t1->value_ < t2->value_) ? -1 : 1; } } static void SetBitDepths(const HuffmanTree* const tree, const HuffmanTree* const pool, uint8_t* const bit_depths, int level) { if (tree->pool_index_left_ >= 0) { SetBitDepths(&pool[tree->pool_index_left_], pool, bit_depths, level + 1); SetBitDepths(&pool[tree->pool_index_right_], pool, bit_depths, level + 1); } else { bit_depths[tree->value_] = level; } } // Create an optimal Huffman tree. // // (data,length): population counts. // tree_limit: maximum bit depth (inclusive) of the codes. // bit_depths[]: how many bits are used for the symbol. // // Returns 0 when an error has occurred. // // The catch here is that the tree cannot be arbitrarily deep // // count_limit is the value that is to be faked as the minimum value // and this minimum value is raised until the tree matches the // maximum length requirement. // // This algorithm is not of excellent performance for very long data blocks, // especially when population counts are longer than 2**tree_limit, but // we are not planning to use this with extremely long blocks. // // See http://en.wikipedia.org/wiki/Huffman_coding static int GenerateOptimalTree(const int* const histogram, int histogram_size, int tree_depth_limit, uint8_t* const bit_depths) { int count_min; HuffmanTree* tree_pool; HuffmanTree* tree; int tree_size_orig = 0; int i; for (i = 0; i < histogram_size; ++i) { if (histogram[i] != 0) { ++tree_size_orig; } } if (tree_size_orig == 0) { // pretty optimal already! return 1; } // 3 * tree_size is enough to cover all the nodes representing a // population and all the inserted nodes combining two existing nodes. // The tree pool needs 2 * (tree_size_orig - 1) entities, and the // tree needs exactly tree_size_orig entities. tree = (HuffmanTree*)WebPSafeMalloc(3ULL * tree_size_orig, sizeof(*tree)); if (tree == NULL) return 0; tree_pool = tree + tree_size_orig; // For block sizes with less than 64k symbols we never need to do a // second iteration of this loop. // If we actually start running inside this loop a lot, we would perhaps // be better off with the Katajainen algorithm. assert(tree_size_orig <= (1 << (tree_depth_limit - 1))); for (count_min = 1; ; count_min *= 2) { int tree_size = tree_size_orig; // We need to pack the Huffman tree in tree_depth_limit bits. // So, we try by faking histogram entries to be at least 'count_min'. int idx = 0; int j; for (j = 0; j < histogram_size; ++j) { if (histogram[j] != 0) { const int count = (histogram[j] < count_min) ? count_min : histogram[j]; tree[idx].total_count_ = count; tree[idx].value_ = j; tree[idx].pool_index_left_ = -1; tree[idx].pool_index_right_ = -1; ++idx; } } // Build the Huffman tree. qsort(tree, tree_size, sizeof(*tree), CompareHuffmanTrees); if (tree_size > 1) { // Normal case. int tree_pool_size = 0; while (tree_size > 1) { // Finish when we have only one root. int count; tree_pool[tree_pool_size++] = tree[tree_size - 1]; tree_pool[tree_pool_size++] = tree[tree_size - 2]; count = tree_pool[tree_pool_size - 1].total_count_ + tree_pool[tree_pool_size - 2].total_count_; tree_size -= 2; { // Search for the insertion point. int k; for (k = 0; k < tree_size; ++k) { if (tree[k].total_count_ <= count) { break; } } memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree)); tree[k].total_count_ = count; tree[k].value_ = -1; tree[k].pool_index_left_ = tree_pool_size - 1; tree[k].pool_index_right_ = tree_pool_size - 2; tree_size = tree_size + 1; } } SetBitDepths(&tree[0], tree_pool, bit_depths, 0); } else if (tree_size == 1) { // Trivial case: only one element. bit_depths[tree[0].value_] = 1; } { // Test if this Huffman tree satisfies our 'tree_depth_limit' criteria. int max_depth = bit_depths[0]; for (j = 1; j < histogram_size; ++j) { if (max_depth < bit_depths[j]) { max_depth = bit_depths[j]; } } if (max_depth <= tree_depth_limit) { break; } } } free(tree); return 1; } // ----------------------------------------------------------------------------- // Coding of the Huffman tree values static HuffmanTreeToken* CodeRepeatedValues(int repetitions, HuffmanTreeToken* tokens, int value, int prev_value) { assert(value <= MAX_ALLOWED_CODE_LENGTH); if (value != prev_value) { tokens->code = value; tokens->extra_bits = 0; ++tokens; --repetitions; } while (repetitions >= 1) { if (repetitions < 3) { int i; for (i = 0; i < repetitions; ++i) { tokens->code = value; tokens->extra_bits = 0; ++tokens; } break; } else if (repetitions < 7) { tokens->code = 16; tokens->extra_bits = repetitions - 3; ++tokens; break; } else { tokens->code = 16; tokens->extra_bits = 3; ++tokens; repetitions -= 6; } } return tokens; } static HuffmanTreeToken* CodeRepeatedZeros(int repetitions, HuffmanTreeToken* tokens) { while (repetitions >= 1) { if (repetitions < 3) { int i; for (i = 0; i < repetitions; ++i) { tokens->code = 0; // 0-value tokens->extra_bits = 0; ++tokens; } break; } else if (repetitions < 11) { tokens->code = 17; tokens->extra_bits = repetitions - 3; ++tokens; break; } else if (repetitions < 139) { tokens->code = 18; tokens->extra_bits = repetitions - 11; ++tokens; break; } else { tokens->code = 18; tokens->extra_bits = 0x7f; // 138 repeated 0s ++tokens; repetitions -= 138; } } return tokens; } int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree, HuffmanTreeToken* tokens, int max_tokens) { HuffmanTreeToken* const starting_token = tokens; HuffmanTreeToken* const ending_token = tokens + max_tokens; const int depth_size = tree->num_symbols; int prev_value = 8; // 8 is the initial value for rle. int i = 0; assert(tokens != NULL); while (i < depth_size) { const int value = tree->code_lengths[i]; int k = i + 1; int runs; while (k < depth_size && tree->code_lengths[k] == value) ++k; runs = k - i; if (value == 0) { tokens = CodeRepeatedZeros(runs, tokens); } else { tokens = CodeRepeatedValues(runs, tokens, value, prev_value); prev_value = value; } i += runs; assert(tokens <= ending_token); } (void)ending_token; // suppress 'unused variable' warning return (int)(tokens - starting_token); } // ----------------------------------------------------------------------------- // Pre-reversed 4-bit values. static const uint8_t kReversedBits[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; static uint32_t ReverseBits(int num_bits, uint32_t bits) { uint32_t retval = 0; int i = 0; while (i < num_bits) { i += 4; retval |= kReversedBits[bits & 0xf] << (MAX_ALLOWED_CODE_LENGTH + 1 - i); bits >>= 4; } retval >>= (MAX_ALLOWED_CODE_LENGTH + 1 - num_bits); return retval; } // Get the actual bit values for a tree of bit depths. static void ConvertBitDepthsToSymbols(HuffmanTreeCode* const tree) { // 0 bit-depth means that the symbol does not exist. int i; int len; uint32_t next_code[MAX_ALLOWED_CODE_LENGTH + 1]; int depth_count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 }; assert(tree != NULL); len = tree->num_symbols; for (i = 0; i < len; ++i) { const int code_length = tree->code_lengths[i]; assert(code_length <= MAX_ALLOWED_CODE_LENGTH); ++depth_count[code_length]; } depth_count[0] = 0; // ignore unused symbol next_code[0] = 0; { uint32_t code = 0; for (i = 1; i <= MAX_ALLOWED_CODE_LENGTH; ++i) { code = (code + depth_count[i - 1]) << 1; next_code[i] = code; } } for (i = 0; i < len; ++i) { const int code_length = tree->code_lengths[i]; tree->codes[i] = ReverseBits(code_length, next_code[code_length]++); } } // ----------------------------------------------------------------------------- // Main entry point int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit, HuffmanTreeCode* const tree) { const int num_symbols = tree->num_symbols; if (!OptimizeHuffmanForRle(num_symbols, histogram)) { return 0; } if (!GenerateOptimalTree(histogram, num_symbols, tree_depth_limit, tree->code_lengths)) { return 0; } // Create the actual bit codes for the bit lengths. ConvertBitDepthsToSymbols(tree); return 1; } libwebp-0.4.0/src/utils/bit_reader.h0000644000014400001440000002610612255002107014246 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Boolean decoder // // Author: Skal (pascal.massimino@gmail.com) // Vikas Arora (vikaas.arora@gmail.com) #ifndef WEBP_UTILS_BIT_READER_H_ #define WEBP_UTILS_BIT_READER_H_ #include #ifdef _MSC_VER #include // _byteswap_ulong #endif #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // The Boolean decoder needs to maintain infinite precision on the value_ field. // However, since range_ is only 8bit, we only need an active window of 8 bits // for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls // below 128, range_ is updated, and fresh bits read from the bitstream are // brought in as LSB. // To avoid reading the fresh bits one by one (slow), we cache a few of them // ahead (actually, we cache BITS of them ahead. See below). There's two // strategies regarding how to shift these looked-ahead fresh bits into the // 8bit window of value_: either we shift them in, while keeping the position of // the window fixed. Or we slide the window to the right while keeping the cache // bits at a fixed, right-justified, position. // // Example, for BITS=16: here is the content of value_ for both strategies: // // !USE_RIGHT_JUSTIFY || USE_RIGHT_JUSTIFY // || // <- 8b -><- 8b -><- BITS bits -> || <- 8b+3b -><- 8b -><- 13 bits -> // [unused][value_][cached bits][0] || [unused...][value_][cached bits] // [........00vvvvvvBBBBBBBBBBBBB000]LSB || [...........00vvvvvvBBBBBBBBBBBBB] // || // After calling VP8Shift(), where we need to shift away two zeros: // [........vvvvvvvvBBBBBBBBBBB00000]LSB || [.............vvvvvvvvBBBBBBBBBBB] // || // Just before we need to call VP8LoadNewBytes(), the situation is: // [........vvvvvv000000000000000000]LSB || [..........................vvvvvv] // || // And just after calling VP8LoadNewBytes(): // [........vvvvvvvvBBBBBBBBBBBBBBBB]LSB || [........vvvvvvvvBBBBBBBBBBBBBBBB] // // -> we're back to eight active 'value_' bits (marked 'v') and BITS cached // bits (marked 'B') // // The right-justify strategy tends to use less shifts and is often faster. //------------------------------------------------------------------------------ // BITS can be any multiple of 8 from 8 to 56 (inclusive). // Pick values that fit natural register size. #if !defined(WEBP_REFERENCE_IMPLEMENTATION) #define USE_RIGHT_JUSTIFY #if defined(__i386__) || defined(_M_IX86) // x86 32bit #define BITS 16 #elif defined(__x86_64__) || defined(_M_X64) // x86 64bit #define BITS 56 #elif defined(__arm__) || defined(_M_ARM) // ARM #define BITS 24 #else // reasonable default #define BITS 24 #endif #else // reference choices #define USE_RIGHT_JUSTIFY #define BITS 8 #endif //------------------------------------------------------------------------------ // Derived types and constants // bit_t = natural register type // lbit_t = natural type for memory I/O #if (BITS > 32) typedef uint64_t bit_t; typedef uint64_t lbit_t; #elif (BITS == 32) typedef uint64_t bit_t; typedef uint32_t lbit_t; #elif (BITS == 24) typedef uint32_t bit_t; typedef uint32_t lbit_t; #elif (BITS == 16) typedef uint32_t bit_t; typedef uint16_t lbit_t; #else typedef uint32_t bit_t; typedef uint8_t lbit_t; #endif #ifndef USE_RIGHT_JUSTIFY typedef bit_t range_t; // type for storing range_ #define MASK ((((bit_t)1) << (BITS)) - 1) #else typedef uint32_t range_t; // range_ only uses 8bits here. No need for bit_t. #endif //------------------------------------------------------------------------------ // Bitreader typedef struct VP8BitReader VP8BitReader; struct VP8BitReader { const uint8_t* buf_; // next byte to be read const uint8_t* buf_end_; // end of read buffer int eof_; // true if input is exhausted // boolean decoder range_t range_; // current range minus 1. In [127, 254] interval. bit_t value_; // current value int bits_; // number of valid bits left }; // Initialize the bit reader and the boolean decoder. void VP8InitBitReader(VP8BitReader* const br, const uint8_t* const start, const uint8_t* const end); // return the next value made of 'num_bits' bits uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) { return VP8GetValue(br, 1); } // return the next value with sign-extension. int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); // Read a bit with proba 'prob'. Speed-critical function! extern const uint8_t kVP8Log2Range[128]; extern const range_t kVP8NewRange[128]; void VP8LoadFinalBytes(VP8BitReader* const br); // special case for the tail static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) { assert(br != NULL && br->buf_ != NULL); // Read 'BITS' bits at a time if possible. if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) { // convert memory type to register type (with some zero'ing!) bit_t bits; const lbit_t in_bits = *(const lbit_t*)br->buf_; br->buf_ += (BITS) >> 3; #if !defined(__BIG_ENDIAN__) #if (BITS > 32) // gcc 4.3 has builtin functions for swap32/swap64 #if defined(__GNUC__) && \ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) bits = (bit_t)__builtin_bswap64(in_bits); #elif defined(_MSC_VER) bits = (bit_t)_byteswap_uint64(in_bits); #elif defined(__x86_64__) __asm__ volatile("bswapq %0" : "=r"(bits) : "0"(in_bits)); #else // generic code for swapping 64-bit values (suggested by bdb@) bits = (bit_t)in_bits; bits = ((bits & 0xffffffff00000000ull) >> 32) | ((bits & 0x00000000ffffffffull) << 32); bits = ((bits & 0xffff0000ffff0000ull) >> 16) | ((bits & 0x0000ffff0000ffffull) << 16); bits = ((bits & 0xff00ff00ff00ff00ull) >> 8) | ((bits & 0x00ff00ff00ff00ffull) << 8); #endif bits >>= 64 - BITS; #elif (BITS >= 24) #if defined(__i386__) || defined(__x86_64__) { lbit_t swapped_in_bits; __asm__ volatile("bswap %k0" : "=r"(swapped_in_bits) : "0"(in_bits)); bits = (bit_t)swapped_in_bits; // 24b/32b -> 32b/64b zero-extension } #elif defined(_MSC_VER) bits = (bit_t)_byteswap_ulong(in_bits); #else bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00) | ((in_bits << 8) & 0xff0000) | (in_bits << 24); #endif // x86 bits >>= (32 - BITS); #elif (BITS == 16) // gcc will recognize a 'rorw $8, ...' here: bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8); #else // BITS == 8 bits = (bit_t)in_bits; #endif #else // BIG_ENDIAN bits = (bit_t)in_bits; if (BITS != 8 * sizeof(bit_t)) bits >>= (8 * sizeof(bit_t) - BITS); #endif #ifndef USE_RIGHT_JUSTIFY br->value_ |= bits << (-br->bits_); #else br->value_ = bits | (br->value_ << (BITS)); #endif br->bits_ += (BITS); } else { VP8LoadFinalBytes(br); // no need to be inlined } } static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, range_t split) { if (br->bits_ < 0) { // Make sure we have a least BITS bits in 'value_' VP8LoadNewBytes(br); } #ifndef USE_RIGHT_JUSTIFY split |= (MASK); if (br->value_ > split) { br->range_ -= split + 1; br->value_ -= split + 1; return 1; } else { br->range_ = split; return 0; } #else { const int pos = br->bits_; const range_t value = (range_t)(br->value_ >> pos); if (value > split) { br->range_ -= split + 1; br->value_ -= (bit_t)(split + 1) << pos; return 1; } else { br->range_ = split; return 0; } } #endif } static WEBP_INLINE void VP8Shift(VP8BitReader* const br) { #ifndef USE_RIGHT_JUSTIFY // range_ is in [0..127] interval here. const bit_t idx = br->range_ >> (BITS); const int shift = kVP8Log2Range[idx]; br->range_ = kVP8NewRange[idx]; br->value_ <<= shift; br->bits_ -= shift; #else const int shift = kVP8Log2Range[br->range_]; assert(br->range_ < (range_t)128); br->range_ = kVP8NewRange[br->range_]; br->bits_ -= shift; #endif } static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) { #ifndef USE_RIGHT_JUSTIFY // It's important to avoid generating a 64bit x 64bit multiply here. // We just need an 8b x 8b after all. const range_t split = (range_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8); const int bit = VP8BitUpdate(br, split); if (br->range_ <= (((range_t)0x7e << (BITS)) | (MASK))) { VP8Shift(br); } return bit; #else const range_t split = (br->range_ * prob) >> 8; const int bit = VP8BitUpdate(br, split); if (br->range_ <= (range_t)0x7e) { VP8Shift(br); } return bit; #endif } static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) { const range_t split = (br->range_ >> 1); const int bit = VP8BitUpdate(br, split); VP8Shift(br); return bit ? -v : v; } // ----------------------------------------------------------------------------- // Bitreader for lossless format typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit. typedef struct { vp8l_val_t val_; // pre-fetched bits const uint8_t* buf_; // input byte buffer size_t len_; // buffer length size_t pos_; // byte position in buf_ int bit_pos_; // current bit-reading position in val_ int eos_; // bitstream is finished int error_; // an error occurred (buffer overflow attempt...) } VP8LBitReader; void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, size_t length); // Sets a new data buffer. void VP8LBitReaderSetBuffer(VP8LBitReader* const br, const uint8_t* const buffer, size_t length); // Reads the specified number of bits from Read Buffer. // Flags an error in case end_of_stream or n_bits is more than allowed limit. // Flags eos if this read attempt is going to cross the read buffer. uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits); // Return the prefetched bits, so they can be looked up. static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) { return (uint32_t)(br->val_ >> br->bit_pos_); } // For jumping over a number of bits in the bit stream when accessed with // VP8LPrefetchBits and VP8LFillBitWindow. static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) { br->bit_pos_ = val; } // Advances the read buffer by 4 bytes to make room for reading next 32 bits. void VP8LFillBitWindow(VP8LBitReader* const br); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_BIT_READER_H_ */ libwebp-0.4.0/src/utils/quant_levels.h0000644000014400001440000000224312255002107014644 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Alpha plane quantization utility // // Author: Vikas Arora (vikasa@google.com) #ifndef WEBP_UTILS_QUANT_LEVELS_H_ #define WEBP_UTILS_QUANT_LEVELS_H_ #include #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // Replace the input 'data' of size 'width'x'height' with 'num-levels' // quantized values. If not NULL, 'sse' will contain the sum of squared error. // Valid range for 'num_levels' is [2, 256]. // Returns false in case of error (data is NULL, or parameters are invalid). int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels, uint64_t* const sse); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_QUANT_LEVELS_H_ */ libwebp-0.4.0/src/utils/color_cache.c0000644000014400001440000000233012255002107014373 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Color Cache for WebP Lossless // // Author: Jyrki Alakuijala (jyrki@google.com) #include #include #include "./color_cache.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ // VP8LColorCache. int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) { const int hash_size = 1 << hash_bits; assert(cc != NULL); assert(hash_bits > 0); cc->colors_ = (uint32_t*)WebPSafeCalloc((uint64_t)hash_size, sizeof(*cc->colors_)); if (cc->colors_ == NULL) return 0; cc->hash_shift_ = 32 - hash_bits; return 1; } void VP8LColorCacheClear(VP8LColorCache* const cc) { if (cc != NULL) { free(cc->colors_); cc->colors_ = NULL; } } libwebp-0.4.0/src/utils/random.h0000644000014400001440000000406412255002107013425 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Pseudo-random utilities // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_UTILS_RANDOM_H_ #define WEBP_UTILS_RANDOM_H_ #include #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif #define VP8_RANDOM_DITHER_FIX 8 // fixed-point precision for dithering #define VP8_RANDOM_TABLE_SIZE 55 typedef struct { int index1_, index2_; uint32_t tab_[VP8_RANDOM_TABLE_SIZE]; int amp_; } VP8Random; // Initializes random generator with an amplitude 'dithering' in range [0..1]. void VP8InitRandom(VP8Random* const rg, float dithering); // Returns a centered pseudo-random number with 'num_bits' amplitude. // (uses D.Knuth's Difference-based random generator). // 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision. static WEBP_INLINE int VP8RandomBits2(VP8Random* const rg, int num_bits, int amp) { int diff; assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31); diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_]; if (diff < 0) diff += (1u << 31); rg->tab_[rg->index1_] = diff; if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0; if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0; diff = (diff << 1) >> (32 - num_bits); // sign-extend, 0-center diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX; // restrict range diff += 1 << (num_bits - 1); // shift back to 0.5-center return diff; } static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) { return VP8RandomBits2(rg, num_bits, rg->amp_); } #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_RANDOM_H_ */ libwebp-0.4.0/src/utils/random.c0000644000014400001440000000344412255002107013421 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Pseudo-random utilities // // Author: Skal (pascal.massimino@gmail.com) #include #include "./random.h" //------------------------------------------------------------------------------ // 31b-range values static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = { 0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828, 0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da, 0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f, 0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2, 0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c, 0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd, 0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3, 0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b, 0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494, 0x27e5ed3c }; void VP8InitRandom(VP8Random* const rg, float dithering) { memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_)); rg->index1_ = 0; rg->index2_ = 31; rg->amp_ = (dithering < 0.0) ? 0 : (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX) : (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering); } //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/alpha_processing.c0000644000014400001440000002255312255002107015464 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utilities for processing transparent channel. // // Author: Skal (pascal.massimino@gmail.com) #include #include "./alpha_processing.h" // Tables can be faster on some platform but incur some extra binary size (~2k). // #define USE_TABLES_FOR_ALPHA_MULT // ----------------------------------------------------------------------------- #define MFIX 24 // 24bit fixed-point arithmetic #define HALF ((1u << MFIX) >> 1) #define KINV_255 ((1u << MFIX) / 255u) static uint32_t Mult(uint8_t x, uint32_t mult) { const uint32_t v = (x * mult + HALF) >> MFIX; assert(v <= 255); // <- 24bit precision is enough to ensure that. return v; } #ifdef USE_TABLES_FOR_ALPHA_MULT static const uint32_t kMultTables[2][256] = { { // (255u << MFIX) / alpha 0x00000000, 0xff000000, 0x7f800000, 0x55000000, 0x3fc00000, 0x33000000, 0x2a800000, 0x246db6db, 0x1fe00000, 0x1c555555, 0x19800000, 0x172e8ba2, 0x15400000, 0x139d89d8, 0x1236db6d, 0x11000000, 0x0ff00000, 0x0f000000, 0x0e2aaaaa, 0x0d6bca1a, 0x0cc00000, 0x0c249249, 0x0b9745d1, 0x0b1642c8, 0x0aa00000, 0x0a333333, 0x09cec4ec, 0x0971c71c, 0x091b6db6, 0x08cb08d3, 0x08800000, 0x0839ce73, 0x07f80000, 0x07ba2e8b, 0x07800000, 0x07492492, 0x07155555, 0x06e45306, 0x06b5e50d, 0x0689d89d, 0x06600000, 0x063831f3, 0x06124924, 0x05ee23b8, 0x05cba2e8, 0x05aaaaaa, 0x058b2164, 0x056cefa8, 0x05500000, 0x05343eb1, 0x05199999, 0x05000000, 0x04e76276, 0x04cfb2b7, 0x04b8e38e, 0x04a2e8ba, 0x048db6db, 0x0479435e, 0x04658469, 0x045270d0, 0x04400000, 0x042e29f7, 0x041ce739, 0x040c30c3, 0x03fc0000, 0x03ec4ec4, 0x03dd1745, 0x03ce540f, 0x03c00000, 0x03b21642, 0x03a49249, 0x03976fc6, 0x038aaaaa, 0x037e3f1f, 0x03722983, 0x03666666, 0x035af286, 0x034fcace, 0x0344ec4e, 0x033a5440, 0x03300000, 0x0325ed09, 0x031c18f9, 0x0312818a, 0x03092492, 0x03000000, 0x02f711dc, 0x02ee5846, 0x02e5d174, 0x02dd7baf, 0x02d55555, 0x02cd5cd5, 0x02c590b2, 0x02bdef7b, 0x02b677d4, 0x02af286b, 0x02a80000, 0x02a0fd5c, 0x029a1f58, 0x029364d9, 0x028ccccc, 0x0286562d, 0x02800000, 0x0279c952, 0x0273b13b, 0x026db6db, 0x0267d95b, 0x026217ec, 0x025c71c7, 0x0256e62a, 0x0251745d, 0x024c1bac, 0x0246db6d, 0x0241b2f9, 0x023ca1af, 0x0237a6f4, 0x0232c234, 0x022df2df, 0x02293868, 0x02249249, 0x02200000, 0x021b810e, 0x021714fb, 0x0212bb51, 0x020e739c, 0x020a3d70, 0x02061861, 0x02020408, 0x01fe0000, 0x01fa0be8, 0x01f62762, 0x01f25213, 0x01ee8ba2, 0x01ead3ba, 0x01e72a07, 0x01e38e38, 0x01e00000, 0x01dc7f10, 0x01d90b21, 0x01d5a3e9, 0x01d24924, 0x01cefa8d, 0x01cbb7e3, 0x01c880e5, 0x01c55555, 0x01c234f7, 0x01bf1f8f, 0x01bc14e5, 0x01b914c1, 0x01b61eed, 0x01b33333, 0x01b05160, 0x01ad7943, 0x01aaaaaa, 0x01a7e567, 0x01a5294a, 0x01a27627, 0x019fcbd2, 0x019d2a20, 0x019a90e7, 0x01980000, 0x01957741, 0x0192f684, 0x01907da4, 0x018e0c7c, 0x018ba2e8, 0x018940c5, 0x0186e5f0, 0x01849249, 0x018245ae, 0x01800000, 0x017dc11f, 0x017b88ee, 0x0179574e, 0x01772c23, 0x01750750, 0x0172e8ba, 0x0170d045, 0x016ebdd7, 0x016cb157, 0x016aaaaa, 0x0168a9b9, 0x0166ae6a, 0x0164b8a7, 0x0162c859, 0x0160dd67, 0x015ef7bd, 0x015d1745, 0x015b3bea, 0x01596596, 0x01579435, 0x0155c7b4, 0x01540000, 0x01523d03, 0x01507eae, 0x014ec4ec, 0x014d0fac, 0x014b5edc, 0x0149b26c, 0x01480a4a, 0x01466666, 0x0144c6af, 0x01432b16, 0x0141938b, 0x01400000, 0x013e7063, 0x013ce4a9, 0x013b5cc0, 0x0139d89d, 0x01385830, 0x0136db6d, 0x01356246, 0x0133ecad, 0x01327a97, 0x01310bf6, 0x012fa0be, 0x012e38e3, 0x012cd459, 0x012b7315, 0x012a150a, 0x0128ba2e, 0x01276276, 0x01260dd6, 0x0124bc44, 0x01236db6, 0x01222222, 0x0120d97c, 0x011f93bc, 0x011e50d7, 0x011d10c4, 0x011bd37a, 0x011a98ef, 0x0119611a, 0x01182bf2, 0x0116f96f, 0x0115c988, 0x01149c34, 0x0113716a, 0x01124924, 0x01112358, 0x01100000, 0x010edf12, 0x010dc087, 0x010ca458, 0x010b8a7d, 0x010a72f0, 0x01095da8, 0x01084a9f, 0x010739ce, 0x01062b2e, 0x01051eb8, 0x01041465, 0x01030c30, 0x01020612, 0x01010204, 0x01000000 }, { // alpha * KINV_255 0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 0x00060606, 0x00070707, 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b, 0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, 0x00101010, 0x00111111, 0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717, 0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d, 0x001e1e1e, 0x001f1f1f, 0x00202020, 0x00212121, 0x00222222, 0x00232323, 0x00242424, 0x00252525, 0x00262626, 0x00272727, 0x00282828, 0x00292929, 0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f, 0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535, 0x00363636, 0x00373737, 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b, 0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, 0x00404040, 0x00414141, 0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747, 0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d, 0x004e4e4e, 0x004f4f4f, 0x00505050, 0x00515151, 0x00525252, 0x00535353, 0x00545454, 0x00555555, 0x00565656, 0x00575757, 0x00585858, 0x00595959, 0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f, 0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565, 0x00666666, 0x00676767, 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b, 0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, 0x00707070, 0x00717171, 0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777, 0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d, 0x007e7e7e, 0x007f7f7f, 0x00808080, 0x00818181, 0x00828282, 0x00838383, 0x00848484, 0x00858585, 0x00868686, 0x00878787, 0x00888888, 0x00898989, 0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f, 0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595, 0x00969696, 0x00979797, 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b, 0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, 0x00a0a0a0, 0x00a1a1a1, 0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7, 0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad, 0x00aeaeae, 0x00afafaf, 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3, 0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, 0x00b8b8b8, 0x00b9b9b9, 0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf, 0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5, 0x00c6c6c6, 0x00c7c7c7, 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb, 0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, 0x00d0d0d0, 0x00d1d1d1, 0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7, 0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd, 0x00dedede, 0x00dfdfdf, 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3, 0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, 0x00e8e8e8, 0x00e9e9e9, 0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef, 0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5, 0x00f6f6f6, 0x00f7f7f7, 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb, 0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff } }; static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { return kMultTables[!inverse][a]; } #else static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { return inverse ? (255u << MFIX) / a : a * KINV_255; } #endif // USE_TABLES_FOR_ALPHA_MULT void WebPMultARGBRow(uint32_t* const ptr, int width, int inverse) { int x; for (x = 0; x < width; ++x) { const uint32_t argb = ptr[x]; if (argb < 0xff000000u) { // alpha < 255 if (argb <= 0x00ffffffu) { // alpha == 0 ptr[x] = 0; } else { const uint32_t alpha = (argb >> 24) & 0xff; const uint32_t scale = GetScale(alpha, inverse); uint32_t out = argb & 0xff000000u; out |= Mult(argb >> 0, scale) << 0; out |= Mult(argb >> 8, scale) << 8; out |= Mult(argb >> 16, scale) << 16; ptr[x] = out; } } } } void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, int inverse) { int n; for (n = 0; n < num_rows; ++n) { WebPMultARGBRow((uint32_t*)ptr, width, inverse); ptr += stride; } } void WebPMultRow(uint8_t* const ptr, const uint8_t* const alpha, int width, int inverse) { int x; for (x = 0; x < width; ++x) { const uint32_t a = alpha[x]; if (a != 255) { if (a == 0) { ptr[x] = 0; } else { const uint32_t scale = GetScale(a, inverse); ptr[x] = Mult(ptr[x], scale); } } } } void WebPMultRows(uint8_t* ptr, int stride, const uint8_t* alpha, int alpha_stride, int width, int num_rows, int inverse) { int n; for (n = 0; n < num_rows; ++n) { WebPMultRow(ptr, alpha, width, inverse); ptr += stride; alpha += alpha_stride; } } #undef KINV_255 #undef HALF #undef MFIX libwebp-0.4.0/src/utils/filters.h0000644000014400001440000000377112255002107013621 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Spatial prediction using various filters // // Author: Urvang (urvang@google.com) #ifndef WEBP_UTILS_FILTERS_H_ #define WEBP_UTILS_FILTERS_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // Filters. typedef enum { WEBP_FILTER_NONE = 0, WEBP_FILTER_HORIZONTAL, WEBP_FILTER_VERTICAL, WEBP_FILTER_GRADIENT, WEBP_FILTER_LAST = WEBP_FILTER_GRADIENT + 1, // end marker WEBP_FILTER_BEST, WEBP_FILTER_FAST } WEBP_FILTER_TYPE; typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height, int stride, uint8_t* out); typedef void (*WebPUnfilterFunc)(int width, int height, int stride, int row, int num_rows, uint8_t* data); // Filter the given data using the given predictor. // 'in' corresponds to a 2-dimensional pixel array of size (stride * height) // in raster order. // 'stride' is number of bytes per scan line (with possible padding). // 'out' should be pre-allocated. extern const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST]; // In-place reconstruct the original data from the given filtered data. // The reconstruction will be done for 'num_rows' rows starting from 'row' // (assuming rows upto 'row - 1' are already reconstructed). extern const WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST]; // Fast estimate of a potentially good filter. WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, int width, int height, int stride); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_FILTERS_H_ */ libwebp-0.4.0/src/utils/bit_reader.c0000644000014400001440000001536512255002107014246 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Boolean decoder // // Author: Skal (pascal.massimino@gmail.com) #include "./bit_reader.h" #ifndef USE_RIGHT_JUSTIFY #define MK(X) (((range_t)(X) << (BITS)) | (MASK)) #else #define MK(X) ((range_t)(X)) #endif //------------------------------------------------------------------------------ // VP8BitReader void VP8InitBitReader(VP8BitReader* const br, const uint8_t* const start, const uint8_t* const end) { assert(br != NULL); assert(start != NULL); assert(start <= end); br->range_ = MK(255 - 1); br->buf_ = start; br->buf_end_ = end; br->value_ = 0; br->bits_ = -8; // to load the very first 8bits br->eof_ = 0; } const uint8_t kVP8Log2Range[128] = { 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }; // range = (range << kVP8Log2Range[range]) + trailing 1's const range_t kVP8NewRange[128] = { MK(127), MK(127), MK(191), MK(127), MK(159), MK(191), MK(223), MK(127), MK(143), MK(159), MK(175), MK(191), MK(207), MK(223), MK(239), MK(127), MK(135), MK(143), MK(151), MK(159), MK(167), MK(175), MK(183), MK(191), MK(199), MK(207), MK(215), MK(223), MK(231), MK(239), MK(247), MK(127), MK(131), MK(135), MK(139), MK(143), MK(147), MK(151), MK(155), MK(159), MK(163), MK(167), MK(171), MK(175), MK(179), MK(183), MK(187), MK(191), MK(195), MK(199), MK(203), MK(207), MK(211), MK(215), MK(219), MK(223), MK(227), MK(231), MK(235), MK(239), MK(243), MK(247), MK(251), MK(127), MK(129), MK(131), MK(133), MK(135), MK(137), MK(139), MK(141), MK(143), MK(145), MK(147), MK(149), MK(151), MK(153), MK(155), MK(157), MK(159), MK(161), MK(163), MK(165), MK(167), MK(169), MK(171), MK(173), MK(175), MK(177), MK(179), MK(181), MK(183), MK(185), MK(187), MK(189), MK(191), MK(193), MK(195), MK(197), MK(199), MK(201), MK(203), MK(205), MK(207), MK(209), MK(211), MK(213), MK(215), MK(217), MK(219), MK(221), MK(223), MK(225), MK(227), MK(229), MK(231), MK(233), MK(235), MK(237), MK(239), MK(241), MK(243), MK(245), MK(247), MK(249), MK(251), MK(253), MK(127) }; #undef MK void VP8LoadFinalBytes(VP8BitReader* const br) { assert(br != NULL && br->buf_ != NULL); // Only read 8bits at a time if (br->buf_ < br->buf_end_) { #ifndef USE_RIGHT_JUSTIFY br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 - br->bits_); #else br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8); #endif br->bits_ += 8; } else if (!br->eof_) { #ifdef USE_RIGHT_JUSTIFY // These are not strictly needed, but it makes the behaviour // consistent for both USE_RIGHT_JUSTIFY and !USE_RIGHT_JUSTIFY. br->value_ <<= 8; br->bits_ += 8; #endif br->eof_ = 1; } } //------------------------------------------------------------------------------ // Higher-level calls uint32_t VP8GetValue(VP8BitReader* const br, int bits) { uint32_t v = 0; while (bits-- > 0) { v |= VP8GetBit(br, 0x80) << bits; } return v; } int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { const int value = VP8GetValue(br, bits); return VP8Get(br) ? -value : value; } //------------------------------------------------------------------------------ // VP8LBitReader #define MAX_NUM_BIT_READ 25 #define LBITS 64 // Number of bits prefetched. #define WBITS 32 // Minimum number of bytes needed after VP8LFillBitWindow. #define LOG8_WBITS 4 // Number of bytes needed to store WBITS bits. static const uint32_t kBitMask[MAX_NUM_BIT_READ] = { 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215 }; void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, size_t length) { size_t i; assert(br != NULL); assert(start != NULL); assert(length < 0xfffffff8u); // can't happen with a RIFF chunk. br->buf_ = start; br->len_ = length; br->val_ = 0; br->pos_ = 0; br->bit_pos_ = 0; br->eos_ = 0; br->error_ = 0; for (i = 0; i < sizeof(br->val_) && i < br->len_; ++i) { br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (8 * i); ++br->pos_; } } void VP8LBitReaderSetBuffer(VP8LBitReader* const br, const uint8_t* const buf, size_t len) { assert(br != NULL); assert(buf != NULL); assert(len < 0xfffffff8u); // can't happen with a RIFF chunk. br->eos_ = (br->pos_ >= len); br->buf_ = buf; br->len_ = len; } // If not at EOS, reload up to LBITS byte-by-byte static void ShiftBytes(VP8LBitReader* const br) { while (br->bit_pos_ >= 8 && br->pos_ < br->len_) { br->val_ >>= 8; br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (LBITS - 8); ++br->pos_; br->bit_pos_ -= 8; } } void VP8LFillBitWindow(VP8LBitReader* const br) { if (br->bit_pos_ >= WBITS) { #if (defined(__x86_64__) || defined(_M_X64)) if (br->pos_ + sizeof(br->val_) < br->len_) { br->val_ >>= WBITS; br->bit_pos_ -= WBITS; // The expression below needs a little-endian arch to work correctly. // This gives a large speedup for decoding speed. br->val_ |= *(const vp8l_val_t*)(br->buf_ + br->pos_) << (LBITS - WBITS); br->pos_ += LOG8_WBITS; return; } #endif ShiftBytes(br); // Slow path. if (br->pos_ == br->len_ && br->bit_pos_ >= LBITS) { br->eos_ = 1; } } } uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) { assert(n_bits >= 0); // Flag an error if end_of_stream or n_bits is more than allowed limit. if (!br->eos_ && n_bits < MAX_NUM_BIT_READ) { const uint32_t val = (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits]; const int new_bits = br->bit_pos_ + n_bits; br->bit_pos_ = new_bits; // If this read is going to cross the read buffer, set the eos flag. if (br->pos_ == br->len_) { if (new_bits >= LBITS) { br->eos_ = 1; } } ShiftBytes(br); return val; } else { br->error_ = 1; return 0; } } //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/utils.h0000644000014400001440000000534612255002107013311 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Misc. common utility functions // // Authors: Skal (pascal.massimino@gmail.com) // Urvang (urvang@google.com) #ifndef WEBP_UTILS_UTILS_H_ #define WEBP_UTILS_UTILS_H_ #include #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Memory allocation // This is the maximum memory amount that libwebp will ever try to allocate. #define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 40) // size-checking safe malloc/calloc: verify that the requested size is not too // large, or return NULL. You don't need to call these for constructs like // malloc(sizeof(foo)), but only if there's picture-dependent size involved // somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this // safe malloc() borrows the signature from calloc(), pointing at the dangerous // underlying multiply involved. void* WebPSafeMalloc(uint64_t nmemb, size_t size); // Note that WebPSafeCalloc() expects the second argument type to be 'size_t' // in order to favor the "calloc(num_foo, sizeof(foo))" pattern. void* WebPSafeCalloc(uint64_t nmemb, size_t size); //------------------------------------------------------------------------------ // Reading/writing data. // Read 16, 24 or 32 bits stored in little-endian order. static WEBP_INLINE int GetLE16(const uint8_t* const data) { return (int)(data[0] << 0) | (data[1] << 8); } static WEBP_INLINE int GetLE24(const uint8_t* const data) { return GetLE16(data) | (data[2] << 16); } static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) { return (uint32_t)GetLE16(data) | (GetLE16(data + 2) << 16); } // Store 16, 24 or 32 bits in little-endian order. static WEBP_INLINE void PutLE16(uint8_t* const data, int val) { assert(val < (1 << 16)); data[0] = (val >> 0); data[1] = (val >> 8); } static WEBP_INLINE void PutLE24(uint8_t* const data, int val) { assert(val < (1 << 24)); PutLE16(data, val & 0xffff); data[2] = (val >> 16); } static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { PutLE16(data, (int)(val & 0xffff)); PutLE16(data + 2, (int)(val >> 16)); } //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_UTILS_H_ */ libwebp-0.4.0/src/utils/filters.c0000644000014400001440000002145012255002107013606 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Spatial prediction using various filters // // Author: Urvang (urvang@google.com) #include "./filters.h" #include #include #include //------------------------------------------------------------------------------ // Helpful macro. # define SANITY_CHECK(in, out) \ assert(in != NULL); \ assert(out != NULL); \ assert(width > 0); \ assert(height > 0); \ assert(stride >= width); \ assert(row >= 0 && num_rows > 0 && row + num_rows <= height); \ (void)height; // Silence unused warning. static WEBP_INLINE void PredictLine(const uint8_t* src, const uint8_t* pred, uint8_t* dst, int length, int inverse) { int i; if (inverse) { for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i]; } else { for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i]; } } //------------------------------------------------------------------------------ // Horizontal filter. static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in, int width, int height, int stride, int row, int num_rows, int inverse, uint8_t* out) { const uint8_t* preds; const size_t start_offset = row * stride; const int last_row = row + num_rows; SANITY_CHECK(in, out); in += start_offset; out += start_offset; preds = inverse ? out : in; if (row == 0) { // Leftmost pixel is the same as input for topmost scanline. out[0] = in[0]; PredictLine(in + 1, preds, out + 1, width - 1, inverse); row = 1; preds += stride; in += stride; out += stride; } // Filter line-by-line. while (row < last_row) { // Leftmost pixel is predicted from above. PredictLine(in, preds - stride, out, 1, inverse); PredictLine(in + 1, preds, out + 1, width - 1, inverse); ++row; preds += stride; in += stride; out += stride; } } static void HorizontalFilter(const uint8_t* data, int width, int height, int stride, uint8_t* filtered_data) { DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data); } static void HorizontalUnfilter(int width, int height, int stride, int row, int num_rows, uint8_t* data) { DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data); } //------------------------------------------------------------------------------ // Vertical filter. static WEBP_INLINE void DoVerticalFilter(const uint8_t* in, int width, int height, int stride, int row, int num_rows, int inverse, uint8_t* out) { const uint8_t* preds; const size_t start_offset = row * stride; const int last_row = row + num_rows; SANITY_CHECK(in, out); in += start_offset; out += start_offset; preds = inverse ? out : in; if (row == 0) { // Very first top-left pixel is copied. out[0] = in[0]; // Rest of top scan-line is left-predicted. PredictLine(in + 1, preds, out + 1, width - 1, inverse); row = 1; in += stride; out += stride; } else { // We are starting from in-between. Make sure 'preds' points to prev row. preds -= stride; } // Filter line-by-line. while (row < last_row) { PredictLine(in, preds, out, width, inverse); ++row; preds += stride; in += stride; out += stride; } } static void VerticalFilter(const uint8_t* data, int width, int height, int stride, uint8_t* filtered_data) { DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data); } static void VerticalUnfilter(int width, int height, int stride, int row, int num_rows, uint8_t* data) { DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data); } //------------------------------------------------------------------------------ // Gradient filter. static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) { const int g = a + b - c; return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit } static WEBP_INLINE void DoGradientFilter(const uint8_t* in, int width, int height, int stride, int row, int num_rows, int inverse, uint8_t* out) { const uint8_t* preds; const size_t start_offset = row * stride; const int last_row = row + num_rows; SANITY_CHECK(in, out); in += start_offset; out += start_offset; preds = inverse ? out : in; // left prediction for top scan-line if (row == 0) { out[0] = in[0]; PredictLine(in + 1, preds, out + 1, width - 1, inverse); row = 1; preds += stride; in += stride; out += stride; } // Filter line-by-line. while (row < last_row) { int w; // leftmost pixel: predict from above. PredictLine(in, preds - stride, out, 1, inverse); for (w = 1; w < width; ++w) { const int pred = GradientPredictor(preds[w - 1], preds[w - stride], preds[w - stride - 1]); out[w] = in[w] + (inverse ? pred : -pred); } ++row; preds += stride; in += stride; out += stride; } } static void GradientFilter(const uint8_t* data, int width, int height, int stride, uint8_t* filtered_data) { DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data); } static void GradientUnfilter(int width, int height, int stride, int row, int num_rows, uint8_t* data) { DoGradientFilter(data, width, height, stride, row, num_rows, 1, data); } #undef SANITY_CHECK // ----------------------------------------------------------------------------- // Quick estimate of a potentially interesting filter mode to try. #define SMAX 16 #define SDIFF(a, b) (abs((a) - (b)) >> 4) // Scoring diff, in [0..SMAX) WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data, int width, int height, int stride) { int i, j; int bins[WEBP_FILTER_LAST][SMAX]; memset(bins, 0, sizeof(bins)); // We only sample every other pixels. That's enough. for (j = 2; j < height - 1; j += 2) { const uint8_t* const p = data + j * stride; int mean = p[0]; for (i = 2; i < width - 1; i += 2) { const int diff0 = SDIFF(p[i], mean); const int diff1 = SDIFF(p[i], p[i - 1]); const int diff2 = SDIFF(p[i], p[i - width]); const int grad_pred = GradientPredictor(p[i - 1], p[i - width], p[i - width - 1]); const int diff3 = SDIFF(p[i], grad_pred); bins[WEBP_FILTER_NONE][diff0] = 1; bins[WEBP_FILTER_HORIZONTAL][diff1] = 1; bins[WEBP_FILTER_VERTICAL][diff2] = 1; bins[WEBP_FILTER_GRADIENT][diff3] = 1; mean = (3 * mean + p[i] + 2) >> 2; } } { int filter; WEBP_FILTER_TYPE best_filter = WEBP_FILTER_NONE; int best_score = 0x7fffffff; for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) { int score = 0; for (i = 0; i < SMAX; ++i) { if (bins[filter][i] > 0) { score += i; } } if (score < best_score) { best_score = score; best_filter = (WEBP_FILTER_TYPE)filter; } } return best_filter; } } #undef SMAX #undef SDIFF //------------------------------------------------------------------------------ const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST] = { NULL, // WEBP_FILTER_NONE HorizontalFilter, // WEBP_FILTER_HORIZONTAL VerticalFilter, // WEBP_FILTER_VERTICAL GradientFilter // WEBP_FILTER_GRADIENT }; const WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST] = { NULL, // WEBP_FILTER_NONE HorizontalUnfilter, // WEBP_FILTER_HORIZONTAL VerticalUnfilter, // WEBP_FILTER_VERTICAL GradientUnfilter // WEBP_FILTER_GRADIENT }; //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/huffman.c0000644000014400001440000002126212255002107013563 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utilities for building and looking up Huffman trees. // // Author: Urvang Joshi (urvang@google.com) #include #include #include #include "./huffman.h" #include "../utils/utils.h" #include "../webp/format_constants.h" // Uncomment the following to use look-up table for ReverseBits() // (might be faster on some platform) // #define USE_LUT_REVERSE_BITS #define NON_EXISTENT_SYMBOL (-1) static void TreeNodeInit(HuffmanTreeNode* const node) { node->children_ = -1; // means: 'unassigned so far' } static int NodeIsEmpty(const HuffmanTreeNode* const node) { return (node->children_ < 0); } static int IsFull(const HuffmanTree* const tree) { return (tree->num_nodes_ == tree->max_nodes_); } static void AssignChildren(HuffmanTree* const tree, HuffmanTreeNode* const node) { HuffmanTreeNode* const children = tree->root_ + tree->num_nodes_; node->children_ = (int)(children - node); assert(children - node == (int)(children - node)); tree->num_nodes_ += 2; TreeNodeInit(children + 0); TreeNodeInit(children + 1); } static int TreeInit(HuffmanTree* const tree, int num_leaves) { assert(tree != NULL); if (num_leaves == 0) return 0; // We allocate maximum possible nodes in the tree at once. // Note that a Huffman tree is a full binary tree; and in a full binary tree // with L leaves, the total number of nodes N = 2 * L - 1. tree->max_nodes_ = 2 * num_leaves - 1; assert(tree->max_nodes_ < (1 << 16)); // limit for the lut_jump_ table tree->root_ = (HuffmanTreeNode*)WebPSafeMalloc((uint64_t)tree->max_nodes_, sizeof(*tree->root_)); if (tree->root_ == NULL) return 0; TreeNodeInit(tree->root_); // Initialize root. tree->num_nodes_ = 1; memset(tree->lut_bits_, 255, sizeof(tree->lut_bits_)); memset(tree->lut_jump_, 0, sizeof(tree->lut_jump_)); return 1; } void HuffmanTreeRelease(HuffmanTree* const tree) { if (tree != NULL) { free(tree->root_); tree->root_ = NULL; tree->max_nodes_ = 0; tree->num_nodes_ = 0; } } int HuffmanCodeLengthsToCodes(const int* const code_lengths, int code_lengths_size, int* const huff_codes) { int symbol; int code_len; int code_length_hist[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 }; int curr_code; int next_codes[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 }; int max_code_length = 0; assert(code_lengths != NULL); assert(code_lengths_size > 0); assert(huff_codes != NULL); // Calculate max code length. for (symbol = 0; symbol < code_lengths_size; ++symbol) { if (code_lengths[symbol] > max_code_length) { max_code_length = code_lengths[symbol]; } } if (max_code_length > MAX_ALLOWED_CODE_LENGTH) return 0; // Calculate code length histogram. for (symbol = 0; symbol < code_lengths_size; ++symbol) { ++code_length_hist[code_lengths[symbol]]; } code_length_hist[0] = 0; // Calculate the initial values of 'next_codes' for each code length. // next_codes[code_len] denotes the code to be assigned to the next symbol // of code length 'code_len'. curr_code = 0; next_codes[0] = -1; // Unused, as code length = 0 implies code doesn't exist. for (code_len = 1; code_len <= max_code_length; ++code_len) { curr_code = (curr_code + code_length_hist[code_len - 1]) << 1; next_codes[code_len] = curr_code; } // Get symbols. for (symbol = 0; symbol < code_lengths_size; ++symbol) { if (code_lengths[symbol] > 0) { huff_codes[symbol] = next_codes[code_lengths[symbol]]++; } else { huff_codes[symbol] = NON_EXISTENT_SYMBOL; } } return 1; } #ifndef USE_LUT_REVERSE_BITS static int ReverseBitsShort(int bits, int num_bits) { int retval = 0; int i; assert(num_bits <= 8); // Not a hard requirement, just for coherency. for (i = 0; i < num_bits; ++i) { retval <<= 1; retval |= bits & 1; bits >>= 1; } return retval; } #else static const uint8_t kReversedBits[16] = { // Pre-reversed 4-bit values. 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; static int ReverseBitsShort(int bits, int num_bits) { const uint8_t v = (kReversedBits[bits & 0xf] << 4) | kReversedBits[bits >> 4]; assert(num_bits <= 8); return v >> (8 - num_bits); } #endif static int TreeAddSymbol(HuffmanTree* const tree, int symbol, int code, int code_length) { int step = HUFF_LUT_BITS; int base_code; HuffmanTreeNode* node = tree->root_; const HuffmanTreeNode* const max_node = tree->root_ + tree->max_nodes_; assert(symbol == (int16_t)symbol); if (code_length <= HUFF_LUT_BITS) { int i; base_code = ReverseBitsShort(code, code_length); for (i = 0; i < (1 << (HUFF_LUT_BITS - code_length)); ++i) { const int idx = base_code | (i << code_length); tree->lut_symbol_[idx] = (int16_t)symbol; tree->lut_bits_[idx] = code_length; } } else { base_code = ReverseBitsShort((code >> (code_length - HUFF_LUT_BITS)), HUFF_LUT_BITS); } while (code_length-- > 0) { if (node >= max_node) { return 0; } if (NodeIsEmpty(node)) { if (IsFull(tree)) return 0; // error: too many symbols. AssignChildren(tree, node); } else if (!HuffmanTreeNodeIsNotLeaf(node)) { return 0; // leaf is already occupied. } node += node->children_ + ((code >> code_length) & 1); if (--step == 0) { tree->lut_jump_[base_code] = (int16_t)(node - tree->root_); } } if (NodeIsEmpty(node)) { node->children_ = 0; // turn newly created node into a leaf. } else if (HuffmanTreeNodeIsNotLeaf(node)) { return 0; // trying to assign a symbol to already used code. } node->symbol_ = symbol; // Add symbol in this node. return 1; } int HuffmanTreeBuildImplicit(HuffmanTree* const tree, const int* const code_lengths, int code_lengths_size) { int symbol; int num_symbols = 0; int root_symbol = 0; assert(tree != NULL); assert(code_lengths != NULL); // Find out number of symbols and the root symbol. for (symbol = 0; symbol < code_lengths_size; ++symbol) { if (code_lengths[symbol] > 0) { // Note: code length = 0 indicates non-existent symbol. ++num_symbols; root_symbol = symbol; } } // Initialize the tree. Will fail for num_symbols = 0 if (!TreeInit(tree, num_symbols)) return 0; // Build tree. if (num_symbols == 1) { // Trivial case. const int max_symbol = code_lengths_size; if (root_symbol < 0 || root_symbol >= max_symbol) { HuffmanTreeRelease(tree); return 0; } return TreeAddSymbol(tree, root_symbol, 0, 0); } else { // Normal case. int ok = 0; // Get Huffman codes from the code lengths. int* const codes = (int*)WebPSafeMalloc((uint64_t)code_lengths_size, sizeof(*codes)); if (codes == NULL) goto End; if (!HuffmanCodeLengthsToCodes(code_lengths, code_lengths_size, codes)) { goto End; } // Add symbols one-by-one. for (symbol = 0; symbol < code_lengths_size; ++symbol) { if (code_lengths[symbol] > 0) { if (!TreeAddSymbol(tree, symbol, codes[symbol], code_lengths[symbol])) { goto End; } } } ok = 1; End: free(codes); ok = ok && IsFull(tree); if (!ok) HuffmanTreeRelease(tree); return ok; } } int HuffmanTreeBuildExplicit(HuffmanTree* const tree, const int* const code_lengths, const int* const codes, const int* const symbols, int max_symbol, int num_symbols) { int ok = 0; int i; assert(tree != NULL); assert(code_lengths != NULL); assert(codes != NULL); assert(symbols != NULL); // Initialize the tree. Will fail if num_symbols = 0. if (!TreeInit(tree, num_symbols)) return 0; // Add symbols one-by-one. for (i = 0; i < num_symbols; ++i) { if (codes[i] != NON_EXISTENT_SYMBOL) { if (symbols[i] < 0 || symbols[i] >= max_symbol) { goto End; } if (!TreeAddSymbol(tree, symbols[i], codes[i], code_lengths[i])) { goto End; } } } ok = 1; End: ok = ok && IsFull(tree); if (!ok) HuffmanTreeRelease(tree); return ok; } libwebp-0.4.0/src/utils/quant_levels_dec.c0000644000014400001440000000151512255002107015453 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // TODO(skal): implement gradient smoothing. // // Author: Skal (pascal.massimino@gmail.com) #include "./quant_levels_dec.h" int DequantizeLevels(uint8_t* const data, int width, int height, int row, int num_rows) { if (data == NULL || width <= 0 || height <= 0 || row < 0 || num_rows < 0 || row + num_rows > height) { return 0; } return 1; } libwebp-0.4.0/src/utils/quant_levels.c0000644000014400001440000000772512255002107014651 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Quantize levels for specified number of quantization-levels ([2, 256]). // Min and max values are preserved (usual 0 and 255 for alpha plane). // // Author: Skal (pascal.massimino@gmail.com) #include #include "./quant_levels.h" #define NUM_SYMBOLS 256 #define MAX_ITER 6 // Maximum number of convergence steps. #define ERROR_THRESHOLD 1e-4 // MSE stopping criterion. // ----------------------------------------------------------------------------- // Quantize levels. int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels, uint64_t* const sse) { int freq[NUM_SYMBOLS] = { 0 }; int q_level[NUM_SYMBOLS] = { 0 }; double inv_q_level[NUM_SYMBOLS] = { 0 }; int min_s = 255, max_s = 0; const size_t data_size = height * width; int i, num_levels_in, iter; double last_err = 1.e38, err = 0.; const double err_threshold = ERROR_THRESHOLD * data_size; if (data == NULL) { return 0; } if (width <= 0 || height <= 0) { return 0; } if (num_levels < 2 || num_levels > 256) { return 0; } { size_t n; num_levels_in = 0; for (n = 0; n < data_size; ++n) { num_levels_in += (freq[data[n]] == 0); if (min_s > data[n]) min_s = data[n]; if (max_s < data[n]) max_s = data[n]; ++freq[data[n]]; } } if (num_levels_in <= num_levels) goto End; // nothing to do! // Start with uniformly spread centroids. for (i = 0; i < num_levels; ++i) { inv_q_level[i] = min_s + (double)(max_s - min_s) * i / (num_levels - 1); } // Fixed values. Won't be changed. q_level[min_s] = 0; q_level[max_s] = num_levels - 1; assert(inv_q_level[0] == min_s); assert(inv_q_level[num_levels - 1] == max_s); // k-Means iterations. for (iter = 0; iter < MAX_ITER; ++iter) { double q_sum[NUM_SYMBOLS] = { 0 }; double q_count[NUM_SYMBOLS] = { 0 }; int s, slot = 0; // Assign classes to representatives. for (s = min_s; s <= max_s; ++s) { // Keep track of the nearest neighbour 'slot' while (slot < num_levels - 1 && 2 * s > inv_q_level[slot] + inv_q_level[slot + 1]) { ++slot; } if (freq[s] > 0) { q_sum[slot] += s * freq[s]; q_count[slot] += freq[s]; } q_level[s] = slot; } // Assign new representatives to classes. if (num_levels > 2) { for (slot = 1; slot < num_levels - 1; ++slot) { const double count = q_count[slot]; if (count > 0.) { inv_q_level[slot] = q_sum[slot] / count; } } } // Compute convergence error. err = 0.; for (s = min_s; s <= max_s; ++s) { const double error = s - inv_q_level[q_level[s]]; err += freq[s] * error * error; } // Check for convergence: we stop as soon as the error is no // longer improving. if (last_err - err < err_threshold) break; last_err = err; } // Remap the alpha plane to quantized values. { // double->int rounding operation can be costly, so we do it // once for all before remapping. We also perform the data[] -> slot // mapping, while at it (avoid one indirection in the final loop). uint8_t map[NUM_SYMBOLS]; int s; size_t n; for (s = min_s; s <= max_s; ++s) { const int slot = q_level[s]; map[s] = (uint8_t)(inv_q_level[slot] + .5); } // Final pass. for (n = 0; n < data_size; ++n) { data[n] = map[data[n]]; } } End: // Store sum of squared error if needed. if (sse != NULL) *sse = (uint64_t)err; return 1; } libwebp-0.4.0/src/utils/rescaler.c0000644000014400001440000001200412255002107013731 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Rescaling functions // // Author: Skal (pascal.massimino@gmail.com) #include #include #include "./rescaler.h" //------------------------------------------------------------------------------ #define RFIX 30 #define MULT_FIX(x, y) (((int64_t)(x) * (y) + (1 << (RFIX - 1))) >> RFIX) void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height, uint8_t* const dst, int dst_width, int dst_height, int dst_stride, int num_channels, int x_add, int x_sub, int y_add, int y_sub, int32_t* const work) { wrk->x_expand = (src_width < dst_width); wrk->src_width = src_width; wrk->src_height = src_height; wrk->dst_width = dst_width; wrk->dst_height = dst_height; wrk->dst = dst; wrk->dst_stride = dst_stride; wrk->num_channels = num_channels; // for 'x_expand', we use bilinear interpolation wrk->x_add = wrk->x_expand ? (x_sub - 1) : x_add - x_sub; wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub; wrk->y_accum = y_add; wrk->y_add = y_add; wrk->y_sub = y_sub; wrk->fx_scale = (1 << RFIX) / x_sub; wrk->fy_scale = (1 << RFIX) / y_sub; wrk->fxy_scale = wrk->x_expand ? ((int64_t)dst_height << RFIX) / (x_sub * src_height) : ((int64_t)dst_height << RFIX) / (x_add * src_height); wrk->irow = work; wrk->frow = work + num_channels * dst_width; } void WebPRescalerImportRow(WebPRescaler* const wrk, const uint8_t* const src, int channel) { const int x_stride = wrk->num_channels; const int x_out_max = wrk->dst_width * wrk->num_channels; int x_in = channel; int x_out; int accum = 0; if (!wrk->x_expand) { int sum = 0; for (x_out = channel; x_out < x_out_max; x_out += x_stride) { accum += wrk->x_add; for (; accum > 0; accum -= wrk->x_sub) { sum += src[x_in]; x_in += x_stride; } { // Emit next horizontal pixel. const int32_t base = src[x_in]; const int32_t frac = base * (-accum); x_in += x_stride; wrk->frow[x_out] = (sum + base) * wrk->x_sub - frac; // fresh fractional start for next pixel sum = (int)MULT_FIX(frac, wrk->fx_scale); } } } else { // simple bilinear interpolation int left = src[channel], right = src[channel]; for (x_out = channel; x_out < x_out_max; x_out += x_stride) { if (accum < 0) { left = right; x_in += x_stride; right = src[x_in]; accum += wrk->x_add; } wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum; accum -= wrk->x_sub; } } // Accumulate the new row's contribution for (x_out = channel; x_out < x_out_max; x_out += x_stride) { wrk->irow[x_out] += wrk->frow[x_out]; } } uint8_t* WebPRescalerExportRow(WebPRescaler* const wrk) { if (wrk->y_accum <= 0) { int x_out; uint8_t* const dst = wrk->dst; int32_t* const irow = wrk->irow; const int32_t* const frow = wrk->frow; const int yscale = wrk->fy_scale * (-wrk->y_accum); const int x_out_max = wrk->dst_width * wrk->num_channels; for (x_out = 0; x_out < x_out_max; ++x_out) { const int frac = (int)MULT_FIX(frow[x_out], yscale); const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale); dst[x_out] = (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255; irow[x_out] = frac; // new fractional start } wrk->y_accum += wrk->y_add; wrk->dst += wrk->dst_stride; return dst; } else { return NULL; } } #undef MULT_FIX #undef RFIX //------------------------------------------------------------------------------ // all-in-one calls int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) { const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub; return (num_lines > max_num_lines) ? max_num_lines : num_lines; } int WebPRescalerImport(WebPRescaler* const wrk, int num_lines, const uint8_t* src, int src_stride) { int total_imported = 0; while (total_imported < num_lines && wrk->y_accum > 0) { int channel; for (channel = 0; channel < wrk->num_channels; ++channel) { WebPRescalerImportRow(wrk, src, channel); } src += src_stride; ++total_imported; wrk->y_accum -= wrk->y_sub; } return total_imported; } int WebPRescalerExport(WebPRescaler* const rescaler) { int total_exported = 0; while (WebPRescalerHasPendingOutput(rescaler)) { WebPRescalerExportRow(rescaler); ++total_exported; } return total_exported; } //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/utils.c0000644000014400001440000000270012255002107013273 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Misc. common utility functions // // Author: Skal (pascal.massimino@gmail.com) #include #include "./utils.h" //------------------------------------------------------------------------------ // Checked memory allocation // Returns 0 in case of overflow of nmemb * size. static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) { const uint64_t total_size = nmemb * size; if (nmemb == 0) return 1; if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0; if (total_size != (size_t)total_size) return 0; return 1; } void* WebPSafeMalloc(uint64_t nmemb, size_t size) { if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL; assert(nmemb * size > 0); return malloc((size_t)(nmemb * size)); } void* WebPSafeCalloc(uint64_t nmemb, size_t size) { if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL; assert(nmemb * size > 0); return calloc((size_t)nmemb, size); } //------------------------------------------------------------------------------ libwebp-0.4.0/src/utils/huffman_encode.h0000644000014400001440000000316012255002107015102 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Author: Jyrki Alakuijala (jyrki@google.com) // // Entropy encoding (Huffman) for webp lossless #ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_ #define WEBP_UTILS_HUFFMAN_ENCODE_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // Struct for holding the tree header in coded form. typedef struct { uint8_t code; // value (0..15) or escape code (16,17,18) uint8_t extra_bits; // extra bits for escape codes } HuffmanTreeToken; // Struct to represent the tree codes (depth and bits array). typedef struct { int num_symbols; // Number of symbols. uint8_t* code_lengths; // Code lengths of the symbols. uint16_t* codes; // Symbol Codes. } HuffmanTreeCode; // Turn the Huffman tree into a token sequence. // Returns the number of tokens used. int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree, HuffmanTreeToken* tokens, int max_tokens); // Create an optimized tree, and tokenize it. int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit, HuffmanTreeCode* const tree); #ifdef __cplusplus } #endif #endif // WEBP_UTILS_HUFFMAN_ENCODE_H_ libwebp-0.4.0/src/utils/quant_levels_dec.h0000644000014400001440000000226212255002107015460 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Alpha plane de-quantization utility // // Author: Vikas Arora (vikasa@google.com) #ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_ #define WEBP_UTILS_QUANT_LEVELS_DEC_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // Apply post-processing to input 'data' of size 'width'x'height' assuming that // the source was quantized to a reduced number of levels. The post-processing // will be applied to 'num_rows' rows of 'data' starting from 'row'. // Returns false in case of error (data is NULL, invalid parameters, ...). int DequantizeLevels(uint8_t* const data, int width, int height, int row, int num_rows); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_QUANT_LEVELS_DEC_H_ */ libwebp-0.4.0/src/utils/bit_writer.h0000644000014400001440000001047112255002107014316 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Bit writing and boolean coder // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_UTILS_BIT_WRITER_H_ #define WEBP_UTILS_BIT_WRITER_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Bit-writing typedef struct VP8BitWriter VP8BitWriter; struct VP8BitWriter { int32_t range_; // range-1 int32_t value_; int run_; // number of outstanding bits int nb_bits_; // number of pending bits uint8_t* buf_; // internal buffer. Re-allocated regularly. Not owned. size_t pos_; size_t max_pos_; int error_; // true in case of error }; // Initialize the object. Allocates some initial memory based on expected_size. int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size); // Finalize the bitstream coding. Returns a pointer to the internal buffer. uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw); // Release any pending memory and zeroes the object. Not a mandatory call. // Only useful in case of error, when the internal buffer hasn't been grabbed! void VP8BitWriterWipeOut(VP8BitWriter* const bw); int VP8PutBit(VP8BitWriter* const bw, int bit, int prob); int VP8PutBitUniform(VP8BitWriter* const bw, int bit); void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits); void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits); // Appends some bytes to the internal buffer. Data is copied. int VP8BitWriterAppend(VP8BitWriter* const bw, const uint8_t* data, size_t size); // return approximate write position (in bits) static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) { return (uint64_t)(bw->pos_ + bw->run_) * 8 + 8 + bw->nb_bits_; } // Returns a pointer to the internal buffer. static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) { return bw->buf_; } // Returns the size of the internal buffer. static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) { return bw->pos_; } //------------------------------------------------------------------------------ // VP8LBitWriter // TODO(vikasa): VP8LBitWriter is copied as-is from lossless code. There's scope // of re-using VP8BitWriter. Will evaluate once basic lossless encoder is // implemented. typedef struct { uint8_t* buf_; size_t bit_pos_; size_t max_bytes_; // After all bits are written, the caller must observe the state of // error_. A value of 1 indicates that a memory allocation failure // has happened during bit writing. A value of 0 indicates successful // writing of bits. int error_; } VP8LBitWriter; static WEBP_INLINE size_t VP8LBitWriterNumBytes(VP8LBitWriter* const bw) { return (bw->bit_pos_ + 7) >> 3; } static WEBP_INLINE uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) { return bw->buf_; } // Returns 0 in case of memory allocation error. int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size); void VP8LBitWriterDestroy(VP8LBitWriter* const bw); // This function writes bits into bytes in increasing addresses, and within // a byte least-significant-bit first. // // The function can write up to 16 bits in one go with WriteBits // Example: let's assume that 3 bits (Rs below) have been written already: // // BYTE-0 BYTE+1 BYTE+2 // // 0000 0RRR 0000 0000 0000 0000 // // Now, we could write 5 or less bits in MSB by just sifting by 3 // and OR'ing to BYTE-0. // // For n bits, we take the last 5 bytes, OR that with high bits in BYTE-0, // and locate the rest in BYTE+1 and BYTE+2. // // VP8LBitWriter's error_ flag is set in case of memory allocation error. void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_BIT_WRITER_H_ */ libwebp-0.4.0/src/utils/rescaler.h0000644000014400001440000000644012255002107013745 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Rescaling functions // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_UTILS_RESCALER_H_ #define WEBP_UTILS_RESCALER_H_ #ifdef __cplusplus extern "C" { #endif #include "../webp/types.h" // Structure used for on-the-fly rescaling typedef struct { int x_expand; // true if we're expanding in the x direction int num_channels; // bytes to jump between pixels int fy_scale, fx_scale; // fixed-point scaling factor int64_t fxy_scale; // '' // we need hpel-precise add/sub increments, for the downsampled U/V planes. int y_accum; // vertical accumulator int y_add, y_sub; // vertical increments (add ~= src, sub ~= dst) int x_add, x_sub; // horizontal increments (add ~= src, sub ~= dst) int src_width, src_height; // source dimensions int dst_width, dst_height; // destination dimensions uint8_t* dst; int dst_stride; int32_t* irow, *frow; // work buffer } WebPRescaler; // Initialize a rescaler given scratch area 'work' and dimensions of src & dst. void WebPRescalerInit(WebPRescaler* const rescaler, int src_width, int src_height, uint8_t* const dst, int dst_width, int dst_height, int dst_stride, int num_channels, int x_add, int x_sub, int y_add, int y_sub, int32_t* const work); // Returns the number of input lines needed next to produce one output line, // considering that the maximum available input lines are 'max_num_lines'. int WebPRescaleNeededLines(const WebPRescaler* const rescaler, int max_num_lines); // Import a row of data and save its contribution in the rescaler. // 'channel' denotes the channel number to be imported. void WebPRescalerImportRow(WebPRescaler* const rescaler, const uint8_t* const src, int channel); // Import multiple rows over all channels, until at least one row is ready to // be exported. Returns the actual number of lines that were imported. int WebPRescalerImport(WebPRescaler* const rescaler, int num_rows, const uint8_t* src, int src_stride); // Return true if there is pending output rows ready. static WEBP_INLINE int WebPRescalerHasPendingOutput(const WebPRescaler* const rescaler) { return (rescaler->y_accum <= 0); } // Export one row from rescaler. Returns the pointer where output was written, // or NULL if no row was pending. uint8_t* WebPRescalerExportRow(WebPRescaler* const rescaler); // Export as many rows as possible. Return the numbers of rows written. int WebPRescalerExport(WebPRescaler* const rescaler); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_RESCALER_H_ */ libwebp-0.4.0/src/utils/Makefile.am0000644000014400001440000000222512255002107014025 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebputils.la if BUILD_LIBWEBPDECODER noinst_LTLIBRARIES += libwebputilsdecode.la endif common_HEADERS = ../webp/types.h commondir = $(includedir)/webp COMMON_SOURCES = COMMON_SOURCES += alpha_processing.c COMMON_SOURCES += alpha_processing.h COMMON_SOURCES += bit_reader.c COMMON_SOURCES += bit_reader.h COMMON_SOURCES += color_cache.c COMMON_SOURCES += color_cache.h COMMON_SOURCES += filters.c COMMON_SOURCES += filters.h COMMON_SOURCES += huffman.c COMMON_SOURCES += huffman.h COMMON_SOURCES += quant_levels_dec.c COMMON_SOURCES += quant_levels_dec.h COMMON_SOURCES += rescaler.c COMMON_SOURCES += rescaler.h COMMON_SOURCES += random.c COMMON_SOURCES += random.h COMMON_SOURCES += thread.c COMMON_SOURCES += thread.h COMMON_SOURCES += utils.c COMMON_SOURCES += utils.h ENC_SOURCES = ENC_SOURCES += bit_writer.c ENC_SOURCES += bit_writer.h ENC_SOURCES += huffman_encode.c ENC_SOURCES += huffman_encode.h ENC_SOURCES += quant_levels.c ENC_SOURCES += quant_levels.h libwebputils_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) if BUILD_LIBWEBPDECODER libwebputilsdecode_la_SOURCES = $(COMMON_SOURCES) endif libwebp-0.4.0/src/utils/thread.h0000644000014400001440000000633112255002107013413 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Multi-threaded worker // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_UTILS_THREAD_H_ #define WEBP_UTILS_THREAD_H_ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __cplusplus extern "C" { #endif #ifdef WEBP_USE_THREAD #if defined(_WIN32) #include typedef HANDLE pthread_t; typedef CRITICAL_SECTION pthread_mutex_t; typedef struct { HANDLE waiting_sem_; HANDLE received_sem_; HANDLE signal_event_; } pthread_cond_t; #else #include #endif /* _WIN32 */ #endif /* WEBP_USE_THREAD */ // State of the worker thread object typedef enum { NOT_OK = 0, // object is unusable OK, // ready to work WORK // busy finishing the current task } WebPWorkerStatus; // Function to be called by the worker thread. Takes two opaque pointers as // arguments (data1 and data2), and should return false in case of error. typedef int (*WebPWorkerHook)(void*, void*); // Synchronize object used to launch job in the worker thread typedef struct { #ifdef WEBP_USE_THREAD pthread_mutex_t mutex_; pthread_cond_t condition_; pthread_t thread_; #endif WebPWorkerStatus status_; WebPWorkerHook hook; // hook to call void* data1; // first argument passed to 'hook' void* data2; // second argument passed to 'hook' int had_error; // return value of the last call to 'hook' } WebPWorker; // Must be called first, before any other method. void WebPWorkerInit(WebPWorker* const worker); // Must be called to initialize the object and spawn the thread. Re-entrant. // Will potentially launch the thread. Returns false in case of error. int WebPWorkerReset(WebPWorker* const worker); // Makes sure the previous work is finished. Returns true if worker->had_error // was not set and no error condition was triggered by the working thread. int WebPWorkerSync(WebPWorker* const worker); // Triggers the thread to call hook() with data1 and data2 argument. These // hook/data1/data2 can be changed at any time before calling this function, // but not be changed afterward until the next call to WebPWorkerSync(). void WebPWorkerLaunch(WebPWorker* const worker); // This function is similar to WebPWorkerLaunch() except that it calls the // hook directly instead of using a thread. Convenient to bypass the thread // mechanism while still using the WebPWorker structs. WebPWorkerSync() must // still be called afterward (for error reporting). void WebPWorkerExecute(WebPWorker* const worker); // Kill the thread and terminate the object. To use the object again, one // must call WebPWorkerReset() again. void WebPWorkerEnd(WebPWorker* const worker); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_UTILS_THREAD_H_ */ libwebp-0.4.0/src/utils/color_cache.h0000644000014400001440000000436412255002107014411 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Color Cache for WebP Lossless // // Authors: Jyrki Alakuijala (jyrki@google.com) // Urvang Joshi (urvang@google.com) #ifndef WEBP_UTILS_COLOR_CACHE_H_ #define WEBP_UTILS_COLOR_CACHE_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif // Main color cache struct. typedef struct { uint32_t *colors_; // color entries int hash_shift_; // Hash shift: 32 - hash_bits. } VP8LColorCache; static const uint32_t kHashMul = 0x1e35a7bd; static WEBP_INLINE uint32_t VP8LColorCacheLookup( const VP8LColorCache* const cc, uint32_t key) { assert(key <= (~0U >> cc->hash_shift_)); return cc->colors_[key]; } static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache* const cc, uint32_t argb) { const uint32_t key = (kHashMul * argb) >> cc->hash_shift_; cc->colors_[key] = argb; } static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache* const cc, uint32_t argb) { return (kHashMul * argb) >> cc->hash_shift_; } static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc, uint32_t argb) { const uint32_t key = (kHashMul * argb) >> cc->hash_shift_; return cc->colors_[key] == argb; } //------------------------------------------------------------------------------ // Initializes the color cache with 'hash_bits' bits for the keys. // Returns false in case of memory error. int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits); // Delete the memory associated to color cache. void VP8LColorCacheClear(VP8LColorCache* const color_cache); //------------------------------------------------------------------------------ #ifdef __cplusplus } #endif #endif // WEBP_UTILS_COLOR_CACHE_H_ libwebp-0.4.0/src/dsp/0000755000014400001440000000000012255206714011430 5ustar libwebp-0.4.0/src/dsp/enc_neon.c0000644000014400001440000005712712255002107013362 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // ARM NEON version of speed-critical encoding functions. // // adapted from libvpx (http://www.webmproject.org/code/) #include "./dsp.h" #if defined(WEBP_USE_NEON) #include "../enc/vp8enci.h" //------------------------------------------------------------------------------ // Transforms (Paragraph 14.4) // Inverse transform. // This code is pretty much the same as TransformOneNEON in the decoder, except // for subtraction to *ref. See the comments there for algorithmic explanations. static void ITransformOne(const uint8_t* ref, const int16_t* in, uint8_t* dst) { const int kBPS = BPS; const int16_t kC1C2[] = { 20091, 17734, 0, 0 }; // kC1 / (kC2 >> 1) / 0 / 0 __asm__ volatile ( "vld1.16 {q1, q2}, [%[in]] \n" "vld1.16 {d0}, [%[kC1C2]] \n" // d2: in[0] // d3: in[8] // d4: in[4] // d5: in[12] "vswp d3, d4 \n" // q8 = {in[4], in[12]} * kC1 * 2 >> 16 // q9 = {in[4], in[12]} * kC2 >> 16 "vqdmulh.s16 q8, q2, d0[0] \n" "vqdmulh.s16 q9, q2, d0[1] \n" // d22 = a = in[0] + in[8] // d23 = b = in[0] - in[8] "vqadd.s16 d22, d2, d3 \n" "vqsub.s16 d23, d2, d3 \n" // q8 = in[4]/[12] * kC1 >> 16 "vshr.s16 q8, q8, #1 \n" // Add {in[4], in[12]} back after the multiplication. "vqadd.s16 q8, q2, q8 \n" // d20 = c = in[4]*kC2 - in[12]*kC1 // d21 = d = in[4]*kC1 + in[12]*kC2 "vqsub.s16 d20, d18, d17 \n" "vqadd.s16 d21, d19, d16 \n" // d2 = tmp[0] = a + d // d3 = tmp[1] = b + c // d4 = tmp[2] = b - c // d5 = tmp[3] = a - d "vqadd.s16 d2, d22, d21 \n" "vqadd.s16 d3, d23, d20 \n" "vqsub.s16 d4, d23, d20 \n" "vqsub.s16 d5, d22, d21 \n" "vzip.16 q1, q2 \n" "vzip.16 q1, q2 \n" "vswp d3, d4 \n" // q8 = {tmp[4], tmp[12]} * kC1 * 2 >> 16 // q9 = {tmp[4], tmp[12]} * kC2 >> 16 "vqdmulh.s16 q8, q2, d0[0] \n" "vqdmulh.s16 q9, q2, d0[1] \n" // d22 = a = tmp[0] + tmp[8] // d23 = b = tmp[0] - tmp[8] "vqadd.s16 d22, d2, d3 \n" "vqsub.s16 d23, d2, d3 \n" "vshr.s16 q8, q8, #1 \n" "vqadd.s16 q8, q2, q8 \n" // d20 = c = in[4]*kC2 - in[12]*kC1 // d21 = d = in[4]*kC1 + in[12]*kC2 "vqsub.s16 d20, d18, d17 \n" "vqadd.s16 d21, d19, d16 \n" // d2 = tmp[0] = a + d // d3 = tmp[1] = b + c // d4 = tmp[2] = b - c // d5 = tmp[3] = a - d "vqadd.s16 d2, d22, d21 \n" "vqadd.s16 d3, d23, d20 \n" "vqsub.s16 d4, d23, d20 \n" "vqsub.s16 d5, d22, d21 \n" "vld1.32 d6[0], [%[ref]], %[kBPS] \n" "vld1.32 d6[1], [%[ref]], %[kBPS] \n" "vld1.32 d7[0], [%[ref]], %[kBPS] \n" "vld1.32 d7[1], [%[ref]], %[kBPS] \n" "sub %[ref], %[ref], %[kBPS], lsl #2 \n" // (val) + 4 >> 3 "vrshr.s16 d2, d2, #3 \n" "vrshr.s16 d3, d3, #3 \n" "vrshr.s16 d4, d4, #3 \n" "vrshr.s16 d5, d5, #3 \n" "vzip.16 q1, q2 \n" "vzip.16 q1, q2 \n" // Must accumulate before saturating "vmovl.u8 q8, d6 \n" "vmovl.u8 q9, d7 \n" "vqadd.s16 q1, q1, q8 \n" "vqadd.s16 q2, q2, q9 \n" "vqmovun.s16 d0, q1 \n" "vqmovun.s16 d1, q2 \n" "vst1.32 d0[0], [%[dst]], %[kBPS] \n" "vst1.32 d0[1], [%[dst]], %[kBPS] \n" "vst1.32 d1[0], [%[dst]], %[kBPS] \n" "vst1.32 d1[1], [%[dst]] \n" : [in] "+r"(in), [dst] "+r"(dst) // modified registers : [kBPS] "r"(kBPS), [kC1C2] "r"(kC1C2), [ref] "r"(ref) // constants : "memory", "q0", "q1", "q2", "q8", "q9", "q10", "q11" // clobbered ); } static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst, int do_two) { ITransformOne(ref, in, dst); if (do_two) { ITransformOne(ref + 4, in + 16, dst + 4); } } // Same code as dec_neon.c static void ITransformWHT(const int16_t* in, int16_t* out) { const int kStep = 32; // The store is only incrementing the pointer as if we // had stored a single byte. __asm__ volatile ( // part 1 // load data into q0, q1 "vld1.16 {q0, q1}, [%[in]] \n" "vaddl.s16 q2, d0, d3 \n" // a0 = in[0] + in[12] "vaddl.s16 q3, d1, d2 \n" // a1 = in[4] + in[8] "vsubl.s16 q4, d1, d2 \n" // a2 = in[4] - in[8] "vsubl.s16 q5, d0, d3 \n" // a3 = in[0] - in[12] "vadd.s32 q0, q2, q3 \n" // tmp[0] = a0 + a1 "vsub.s32 q2, q2, q3 \n" // tmp[8] = a0 - a1 "vadd.s32 q1, q5, q4 \n" // tmp[4] = a3 + a2 "vsub.s32 q3, q5, q4 \n" // tmp[12] = a3 - a2 // Transpose // q0 = tmp[0, 4, 8, 12], q1 = tmp[2, 6, 10, 14] // q2 = tmp[1, 5, 9, 13], q3 = tmp[3, 7, 11, 15] "vswp d1, d4 \n" // vtrn.64 q0, q2 "vswp d3, d6 \n" // vtrn.64 q1, q3 "vtrn.32 q0, q1 \n" "vtrn.32 q2, q3 \n" "vmov.s32 q4, #3 \n" // dc = 3 "vadd.s32 q0, q0, q4 \n" // dc = tmp[0] + 3 "vadd.s32 q6, q0, q3 \n" // a0 = dc + tmp[3] "vadd.s32 q7, q1, q2 \n" // a1 = tmp[1] + tmp[2] "vsub.s32 q8, q1, q2 \n" // a2 = tmp[1] - tmp[2] "vsub.s32 q9, q0, q3 \n" // a3 = dc - tmp[3] "vadd.s32 q0, q6, q7 \n" "vshrn.s32 d0, q0, #3 \n" // (a0 + a1) >> 3 "vadd.s32 q1, q9, q8 \n" "vshrn.s32 d1, q1, #3 \n" // (a3 + a2) >> 3 "vsub.s32 q2, q6, q7 \n" "vshrn.s32 d2, q2, #3 \n" // (a0 - a1) >> 3 "vsub.s32 q3, q9, q8 \n" "vshrn.s32 d3, q3, #3 \n" // (a3 - a2) >> 3 // set the results to output "vst1.16 d0[0], [%[out]], %[kStep] \n" "vst1.16 d1[0], [%[out]], %[kStep] \n" "vst1.16 d2[0], [%[out]], %[kStep] \n" "vst1.16 d3[0], [%[out]], %[kStep] \n" "vst1.16 d0[1], [%[out]], %[kStep] \n" "vst1.16 d1[1], [%[out]], %[kStep] \n" "vst1.16 d2[1], [%[out]], %[kStep] \n" "vst1.16 d3[1], [%[out]], %[kStep] \n" "vst1.16 d0[2], [%[out]], %[kStep] \n" "vst1.16 d1[2], [%[out]], %[kStep] \n" "vst1.16 d2[2], [%[out]], %[kStep] \n" "vst1.16 d3[2], [%[out]], %[kStep] \n" "vst1.16 d0[3], [%[out]], %[kStep] \n" "vst1.16 d1[3], [%[out]], %[kStep] \n" "vst1.16 d2[3], [%[out]], %[kStep] \n" "vst1.16 d3[3], [%[out]], %[kStep] \n" : [out] "+r"(out) // modified registers : [in] "r"(in), [kStep] "r"(kStep) // constants : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9" // clobbered ); } // Forward transform. // adapted from vp8/encoder/arm/neon/shortfdct_neon.asm static const int16_t kCoeff16[] = { 5352, 5352, 5352, 5352, 2217, 2217, 2217, 2217 }; static const int32_t kCoeff32[] = { 1812, 1812, 1812, 1812, 937, 937, 937, 937, 12000, 12000, 12000, 12000, 51000, 51000, 51000, 51000 }; static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) { const int kBPS = BPS; const uint8_t* src_ptr = src; const uint8_t* ref_ptr = ref; const int16_t* coeff16 = kCoeff16; const int32_t* coeff32 = kCoeff32; __asm__ volatile ( // load src into q4, q5 in high half "vld1.8 {d8}, [%[src_ptr]], %[kBPS] \n" "vld1.8 {d10}, [%[src_ptr]], %[kBPS] \n" "vld1.8 {d9}, [%[src_ptr]], %[kBPS] \n" "vld1.8 {d11}, [%[src_ptr]] \n" // load ref into q6, q7 in high half "vld1.8 {d12}, [%[ref_ptr]], %[kBPS] \n" "vld1.8 {d14}, [%[ref_ptr]], %[kBPS] \n" "vld1.8 {d13}, [%[ref_ptr]], %[kBPS] \n" "vld1.8 {d15}, [%[ref_ptr]] \n" // Pack the high values in to q4 and q6 "vtrn.32 q4, q5 \n" "vtrn.32 q6, q7 \n" // d[0-3] = src - ref "vsubl.u8 q0, d8, d12 \n" "vsubl.u8 q1, d9, d13 \n" // load coeff16 into q8(d16=5352, d17=2217) "vld1.16 {q8}, [%[coeff16]] \n" // load coeff32 high half into q9 = 1812, q10 = 937 "vld1.32 {q9, q10}, [%[coeff32]]! \n" // load coeff32 low half into q11=12000, q12=51000 "vld1.32 {q11,q12}, [%[coeff32]] \n" // part 1 // Transpose. Register dN is the same as dN in C "vtrn.32 d0, d2 \n" "vtrn.32 d1, d3 \n" "vtrn.16 d0, d1 \n" "vtrn.16 d2, d3 \n" "vadd.s16 d4, d0, d3 \n" // a0 = d0 + d3 "vadd.s16 d5, d1, d2 \n" // a1 = d1 + d2 "vsub.s16 d6, d1, d2 \n" // a2 = d1 - d2 "vsub.s16 d7, d0, d3 \n" // a3 = d0 - d3 "vadd.s16 d0, d4, d5 \n" // a0 + a1 "vshl.s16 d0, d0, #3 \n" // temp[0+i*4] = (a0+a1) << 3 "vsub.s16 d2, d4, d5 \n" // a0 - a1 "vshl.s16 d2, d2, #3 \n" // (temp[2+i*4] = (a0-a1) << 3 "vmlal.s16 q9, d7, d16 \n" // a3*5352 + 1812 "vmlal.s16 q10, d7, d17 \n" // a3*2217 + 937 "vmlal.s16 q9, d6, d17 \n" // a2*2217 + a3*5352 + 1812 "vmlsl.s16 q10, d6, d16 \n" // a3*2217 + 937 - a2*5352 // temp[1+i*4] = (d2*2217 + d3*5352 + 1812) >> 9 // temp[3+i*4] = (d3*2217 + 937 - d2*5352) >> 9 "vshrn.s32 d1, q9, #9 \n" "vshrn.s32 d3, q10, #9 \n" // part 2 // transpose d0=ip[0], d1=ip[4], d2=ip[8], d3=ip[12] "vtrn.32 d0, d2 \n" "vtrn.32 d1, d3 \n" "vtrn.16 d0, d1 \n" "vtrn.16 d2, d3 \n" "vmov.s16 d26, #7 \n" "vadd.s16 d4, d0, d3 \n" // a1 = ip[0] + ip[12] "vadd.s16 d5, d1, d2 \n" // b1 = ip[4] + ip[8] "vsub.s16 d6, d1, d2 \n" // c1 = ip[4] - ip[8] "vadd.s16 d4, d4, d26 \n" // a1 + 7 "vsub.s16 d7, d0, d3 \n" // d1 = ip[0] - ip[12] "vadd.s16 d0, d4, d5 \n" // op[0] = a1 + b1 + 7 "vsub.s16 d2, d4, d5 \n" // op[8] = a1 - b1 + 7 "vmlal.s16 q11, d7, d16 \n" // d1*5352 + 12000 "vmlal.s16 q12, d7, d17 \n" // d1*2217 + 51000 "vceq.s16 d4, d7, #0 \n" "vshr.s16 d0, d0, #4 \n" "vshr.s16 d2, d2, #4 \n" "vmlal.s16 q11, d6, d17 \n" // c1*2217 + d1*5352 + 12000 "vmlsl.s16 q12, d6, d16 \n" // d1*2217 - c1*5352 + 51000 "vmvn d4, d4 \n" // !(d1 == 0) // op[4] = (c1*2217 + d1*5352 + 12000)>>16 "vshrn.s32 d1, q11, #16 \n" // op[4] += (d1!=0) "vsub.s16 d1, d1, d4 \n" // op[12]= (d1*2217 - c1*5352 + 51000)>>16 "vshrn.s32 d3, q12, #16 \n" // set result to out array "vst1.16 {q0, q1}, [%[out]] \n" : [src_ptr] "+r"(src_ptr), [ref_ptr] "+r"(ref_ptr), [coeff32] "+r"(coeff32) // modified registers : [kBPS] "r"(kBPS), [coeff16] "r"(coeff16), [out] "r"(out) // constants : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13" // clobbered ); } static void FTransformWHT(const int16_t* in, int16_t* out) { const int kStep = 32; __asm__ volatile ( // d0 = in[0 * 16] , d1 = in[1 * 16] // d2 = in[2 * 16] , d3 = in[3 * 16] "vld1.16 d0[0], [%[in]], %[kStep] \n" "vld1.16 d1[0], [%[in]], %[kStep] \n" "vld1.16 d2[0], [%[in]], %[kStep] \n" "vld1.16 d3[0], [%[in]], %[kStep] \n" "vld1.16 d0[1], [%[in]], %[kStep] \n" "vld1.16 d1[1], [%[in]], %[kStep] \n" "vld1.16 d2[1], [%[in]], %[kStep] \n" "vld1.16 d3[1], [%[in]], %[kStep] \n" "vld1.16 d0[2], [%[in]], %[kStep] \n" "vld1.16 d1[2], [%[in]], %[kStep] \n" "vld1.16 d2[2], [%[in]], %[kStep] \n" "vld1.16 d3[2], [%[in]], %[kStep] \n" "vld1.16 d0[3], [%[in]], %[kStep] \n" "vld1.16 d1[3], [%[in]], %[kStep] \n" "vld1.16 d2[3], [%[in]], %[kStep] \n" "vld1.16 d3[3], [%[in]], %[kStep] \n" "vaddl.s16 q2, d0, d2 \n" // a0=(in[0*16]+in[2*16]) "vaddl.s16 q3, d1, d3 \n" // a1=(in[1*16]+in[3*16]) "vsubl.s16 q4, d1, d3 \n" // a2=(in[1*16]-in[3*16]) "vsubl.s16 q5, d0, d2 \n" // a3=(in[0*16]-in[2*16]) "vqadd.s32 q6, q2, q3 \n" // a0 + a1 "vqadd.s32 q7, q5, q4 \n" // a3 + a2 "vqsub.s32 q8, q5, q4 \n" // a3 - a2 "vqsub.s32 q9, q2, q3 \n" // a0 - a1 // Transpose // q6 = tmp[0, 1, 2, 3] ; q7 = tmp[ 4, 5, 6, 7] // q8 = tmp[8, 9, 10, 11] ; q9 = tmp[12, 13, 14, 15] "vswp d13, d16 \n" // vtrn.64 q0, q2 "vswp d15, d18 \n" // vtrn.64 q1, q3 "vtrn.32 q6, q7 \n" "vtrn.32 q8, q9 \n" "vqadd.s32 q0, q6, q8 \n" // a0 = tmp[0] + tmp[8] "vqadd.s32 q1, q7, q9 \n" // a1 = tmp[4] + tmp[12] "vqsub.s32 q2, q7, q9 \n" // a2 = tmp[4] - tmp[12] "vqsub.s32 q3, q6, q8 \n" // a3 = tmp[0] - tmp[8] "vqadd.s32 q4, q0, q1 \n" // b0 = a0 + a1 "vqadd.s32 q5, q3, q2 \n" // b1 = a3 + a2 "vqsub.s32 q6, q3, q2 \n" // b2 = a3 - a2 "vqsub.s32 q7, q0, q1 \n" // b3 = a0 - a1 "vshrn.s32 d18, q4, #1 \n" // b0 >> 1 "vshrn.s32 d19, q5, #1 \n" // b1 >> 1 "vshrn.s32 d20, q6, #1 \n" // b2 >> 1 "vshrn.s32 d21, q7, #1 \n" // b3 >> 1 "vst1.16 {q9, q10}, [%[out]] \n" : [in] "+r"(in) : [kStep] "r"(kStep), [out] "r"(out) : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10" // clobbered ) ; } //------------------------------------------------------------------------------ // Texture distortion // // We try to match the spectral content (weighted) between source and // reconstructed samples. // Hadamard transform // Returns the weighted sum of the absolute value of transformed coefficients. // This uses a TTransform helper function in C static int Disto4x4(const uint8_t* const a, const uint8_t* const b, const uint16_t* const w) { const int kBPS = BPS; const uint8_t* A = a; const uint8_t* B = b; const uint16_t* W = w; int sum; __asm__ volatile ( "vld1.32 d0[0], [%[a]], %[kBPS] \n" "vld1.32 d0[1], [%[a]], %[kBPS] \n" "vld1.32 d2[0], [%[a]], %[kBPS] \n" "vld1.32 d2[1], [%[a]] \n" "vld1.32 d1[0], [%[b]], %[kBPS] \n" "vld1.32 d1[1], [%[b]], %[kBPS] \n" "vld1.32 d3[0], [%[b]], %[kBPS] \n" "vld1.32 d3[1], [%[b]] \n" // a d0/d2, b d1/d3 // d0/d1: 01 01 01 01 // d2/d3: 23 23 23 23 // But: it goes 01 45 23 67 // Notice the middle values are transposed "vtrn.16 q0, q1 \n" // {a0, a1} = {in[0] + in[2], in[1] + in[3]} "vaddl.u8 q2, d0, d2 \n" "vaddl.u8 q10, d1, d3 \n" // {a3, a2} = {in[0] - in[2], in[1] - in[3]} "vsubl.u8 q3, d0, d2 \n" "vsubl.u8 q11, d1, d3 \n" // tmp[0] = a0 + a1 "vpaddl.s16 q0, q2 \n" "vpaddl.s16 q8, q10 \n" // tmp[1] = a3 + a2 "vpaddl.s16 q1, q3 \n" "vpaddl.s16 q9, q11 \n" // No pair subtract // q2 = {a0, a3} // q3 = {a1, a2} "vtrn.16 q2, q3 \n" "vtrn.16 q10, q11 \n" // {tmp[3], tmp[2]} = {a0 - a1, a3 - a2} "vsubl.s16 q12, d4, d6 \n" "vsubl.s16 q13, d5, d7 \n" "vsubl.s16 q14, d20, d22 \n" "vsubl.s16 q15, d21, d23 \n" // separate tmp[3] and tmp[2] // q12 = tmp[3] // q13 = tmp[2] "vtrn.32 q12, q13 \n" "vtrn.32 q14, q15 \n" // Transpose tmp for a "vswp d1, d26 \n" // vtrn.64 "vswp d3, d24 \n" // vtrn.64 "vtrn.32 q0, q1 \n" "vtrn.32 q13, q12 \n" // Transpose tmp for b "vswp d17, d30 \n" // vtrn.64 "vswp d19, d28 \n" // vtrn.64 "vtrn.32 q8, q9 \n" "vtrn.32 q15, q14 \n" // The first Q register is a, the second b. // q0/8 tmp[0-3] // q13/15 tmp[4-7] // q1/9 tmp[8-11] // q12/14 tmp[12-15] // These are still in 01 45 23 67 order. We fix it easily in the addition // case but the subtraction propagates them. "vswp d3, d27 \n" "vswp d19, d31 \n" // a0 = tmp[0] + tmp[8] "vadd.s32 q2, q0, q1 \n" "vadd.s32 q3, q8, q9 \n" // a1 = tmp[4] + tmp[12] "vadd.s32 q10, q13, q12 \n" "vadd.s32 q11, q15, q14 \n" // a2 = tmp[4] - tmp[12] "vsub.s32 q13, q13, q12 \n" "vsub.s32 q15, q15, q14 \n" // a3 = tmp[0] - tmp[8] "vsub.s32 q0, q0, q1 \n" "vsub.s32 q8, q8, q9 \n" // b0 = a0 + a1 "vadd.s32 q1, q2, q10 \n" "vadd.s32 q9, q3, q11 \n" // b1 = a3 + a2 "vadd.s32 q12, q0, q13 \n" "vadd.s32 q14, q8, q15 \n" // b2 = a3 - a2 "vsub.s32 q0, q0, q13 \n" "vsub.s32 q8, q8, q15 \n" // b3 = a0 - a1 "vsub.s32 q2, q2, q10 \n" "vsub.s32 q3, q3, q11 \n" "vld1.64 {q10, q11}, [%[w]] \n" // abs(b0) "vabs.s32 q1, q1 \n" "vabs.s32 q9, q9 \n" // abs(b1) "vabs.s32 q12, q12 \n" "vabs.s32 q14, q14 \n" // abs(b2) "vabs.s32 q0, q0 \n" "vabs.s32 q8, q8 \n" // abs(b3) "vabs.s32 q2, q2 \n" "vabs.s32 q3, q3 \n" // expand w before using. "vmovl.u16 q13, d20 \n" "vmovl.u16 q15, d21 \n" // w[0] * abs(b0) "vmul.u32 q1, q1, q13 \n" "vmul.u32 q9, q9, q13 \n" // w[4] * abs(b1) "vmla.u32 q1, q12, q15 \n" "vmla.u32 q9, q14, q15 \n" // expand w before using. "vmovl.u16 q13, d22 \n" "vmovl.u16 q15, d23 \n" // w[8] * abs(b1) "vmla.u32 q1, q0, q13 \n" "vmla.u32 q9, q8, q13 \n" // w[12] * abs(b1) "vmla.u32 q1, q2, q15 \n" "vmla.u32 q9, q3, q15 \n" // Sum the arrays "vpaddl.u32 q1, q1 \n" "vpaddl.u32 q9, q9 \n" "vadd.u64 d2, d3 \n" "vadd.u64 d18, d19 \n" // Hadamard transform needs 4 bits of extra precision (2 bits in each // direction) for dynamic raw. Weights w[] are 16bits at max, so the maximum // precision for coeff is 8bit of input + 4bits of Hadamard transform + // 16bits for w[] + 2 bits of abs() summation. // // This uses a maximum of 31 bits (signed). Discarding the top 32 bits is // A-OK. // sum2 - sum1 "vsub.u32 d0, d2, d18 \n" // abs(sum2 - sum1) "vabs.s32 d0, d0 \n" // abs(sum2 - sum1) >> 5 "vshr.u32 d0, #5 \n" // It would be better to move the value straight into r0 but I'm not // entirely sure how this works with inline assembly. "vmov.32 %[sum], d0[0] \n" : [sum] "=r"(sum), [a] "+r"(A), [b] "+r"(B), [w] "+r"(W) : [kBPS] "r"(kBPS) : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" // clobbered ) ; return sum; } static int Disto16x16(const uint8_t* const a, const uint8_t* const b, const uint16_t* const w) { int D = 0; int x, y; for (y = 0; y < 16 * BPS; y += 4 * BPS) { for (x = 0; x < 16; x += 4) { D += Disto4x4(a + x + y, b + x + y, w); } } return D; } #endif // WEBP_USE_NEON //------------------------------------------------------------------------------ // Entry point extern void VP8EncDspInitNEON(void); void VP8EncDspInitNEON(void) { #if defined(WEBP_USE_NEON) VP8ITransform = ITransform; VP8FTransform = FTransform; VP8ITransformWHT = ITransformWHT; VP8FTransformWHT = FTransformWHT; VP8TDisto4x4 = Disto4x4; VP8TDisto16x16 = Disto16x16; #endif // WEBP_USE_NEON } libwebp-0.4.0/src/dsp/enc.c0000644000014400001440000005351512255002107012340 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Speed-critical encoding functions. // // Author: Skal (pascal.massimino@gmail.com) #include #include // for abs() #include "./dsp.h" #include "../enc/vp8enci.h" static WEBP_INLINE uint8_t clip_8b(int v) { return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255; } static WEBP_INLINE int clip_max(int v, int max) { return (v > max) ? max : v; } //------------------------------------------------------------------------------ // Compute susceptibility based on DCT-coeff histograms: // the higher, the "easier" the macroblock is to compress. const int VP8DspScan[16 + 4 + 4] = { // Luma 0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS, 0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * BPS, 0 + 8 * BPS, 4 + 8 * BPS, 8 + 8 * BPS, 12 + 8 * BPS, 0 + 12 * BPS, 4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS, 0 + 0 * BPS, 4 + 0 * BPS, 0 + 4 * BPS, 4 + 4 * BPS, // U 8 + 0 * BPS, 12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS // V }; static void CollectHistogram(const uint8_t* ref, const uint8_t* pred, int start_block, int end_block, VP8Histogram* const histo) { int j; for (j = start_block; j < end_block; ++j) { int k; int16_t out[16]; VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out); // Convert coefficients to bin. for (k = 0; k < 16; ++k) { const int v = abs(out[k]) >> 3; // TODO(skal): add rounding? const int clipped_value = clip_max(v, MAX_COEFF_THRESH); histo->distribution[clipped_value]++; } } } //------------------------------------------------------------------------------ // run-time tables (~4k) static uint8_t clip1[255 + 510 + 1]; // clips [-255,510] to [0,255] // We declare this variable 'volatile' to prevent instruction reordering // and make sure it's set to true _last_ (so as to be thread-safe) static volatile int tables_ok = 0; static void InitTables(void) { if (!tables_ok) { int i; for (i = -255; i <= 255 + 255; ++i) { clip1[255 + i] = clip_8b(i); } tables_ok = 1; } } //------------------------------------------------------------------------------ // Transforms (Paragraph 14.4) #define STORE(x, y, v) \ dst[(x) + (y) * BPS] = clip_8b(ref[(x) + (y) * BPS] + ((v) >> 3)) static const int kC1 = 20091 + (1 << 16); static const int kC2 = 35468; #define MUL(a, b) (((a) * (b)) >> 16) static WEBP_INLINE void ITransformOne(const uint8_t* ref, const int16_t* in, uint8_t* dst) { int C[4 * 4], *tmp; int i; tmp = C; for (i = 0; i < 4; ++i) { // vertical pass const int a = in[0] + in[8]; const int b = in[0] - in[8]; const int c = MUL(in[4], kC2) - MUL(in[12], kC1); const int d = MUL(in[4], kC1) + MUL(in[12], kC2); tmp[0] = a + d; tmp[1] = b + c; tmp[2] = b - c; tmp[3] = a - d; tmp += 4; in++; } tmp = C; for (i = 0; i < 4; ++i) { // horizontal pass const int dc = tmp[0] + 4; const int a = dc + tmp[8]; const int b = dc - tmp[8]; const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1); const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2); STORE(0, i, a + d); STORE(1, i, b + c); STORE(2, i, b - c); STORE(3, i, a - d); tmp++; } } static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst, int do_two) { ITransformOne(ref, in, dst); if (do_two) { ITransformOne(ref + 4, in + 16, dst + 4); } } static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) { int i; int tmp[16]; for (i = 0; i < 4; ++i, src += BPS, ref += BPS) { const int d0 = src[0] - ref[0]; // 9bit dynamic range ([-255,255]) const int d1 = src[1] - ref[1]; const int d2 = src[2] - ref[2]; const int d3 = src[3] - ref[3]; const int a0 = (d0 + d3); // 10b [-510,510] const int a1 = (d1 + d2); const int a2 = (d1 - d2); const int a3 = (d0 - d3); tmp[0 + i * 4] = (a0 + a1) * 8; // 14b [-8160,8160] tmp[1 + i * 4] = (a2 * 2217 + a3 * 5352 + 1812) >> 9; // [-7536,7542] tmp[2 + i * 4] = (a0 - a1) * 8; tmp[3 + i * 4] = (a3 * 2217 - a2 * 5352 + 937) >> 9; } for (i = 0; i < 4; ++i) { const int a0 = (tmp[0 + i] + tmp[12 + i]); // 15b const int a1 = (tmp[4 + i] + tmp[ 8 + i]); const int a2 = (tmp[4 + i] - tmp[ 8 + i]); const int a3 = (tmp[0 + i] - tmp[12 + i]); out[0 + i] = (a0 + a1 + 7) >> 4; // 12b out[4 + i] = ((a2 * 2217 + a3 * 5352 + 12000) >> 16) + (a3 != 0); out[8 + i] = (a0 - a1 + 7) >> 4; out[12+ i] = ((a3 * 2217 - a2 * 5352 + 51000) >> 16); } } static void ITransformWHT(const int16_t* in, int16_t* out) { int tmp[16]; int i; for (i = 0; i < 4; ++i) { const int a0 = in[0 + i] + in[12 + i]; const int a1 = in[4 + i] + in[ 8 + i]; const int a2 = in[4 + i] - in[ 8 + i]; const int a3 = in[0 + i] - in[12 + i]; tmp[0 + i] = a0 + a1; tmp[8 + i] = a0 - a1; tmp[4 + i] = a3 + a2; tmp[12 + i] = a3 - a2; } for (i = 0; i < 4; ++i) { const int dc = tmp[0 + i * 4] + 3; // w/ rounder const int a0 = dc + tmp[3 + i * 4]; const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4]; const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4]; const int a3 = dc - tmp[3 + i * 4]; out[ 0] = (a0 + a1) >> 3; out[16] = (a3 + a2) >> 3; out[32] = (a0 - a1) >> 3; out[48] = (a3 - a2) >> 3; out += 64; } } static void FTransformWHT(const int16_t* in, int16_t* out) { // input is 12b signed int32_t tmp[16]; int i; for (i = 0; i < 4; ++i, in += 64) { const int a0 = (in[0 * 16] + in[2 * 16]); // 13b const int a1 = (in[1 * 16] + in[3 * 16]); const int a2 = (in[1 * 16] - in[3 * 16]); const int a3 = (in[0 * 16] - in[2 * 16]); tmp[0 + i * 4] = a0 + a1; // 14b tmp[1 + i * 4] = a3 + a2; tmp[2 + i * 4] = a3 - a2; tmp[3 + i * 4] = a0 - a1; } for (i = 0; i < 4; ++i) { const int a0 = (tmp[0 + i] + tmp[8 + i]); // 15b const int a1 = (tmp[4 + i] + tmp[12+ i]); const int a2 = (tmp[4 + i] - tmp[12+ i]); const int a3 = (tmp[0 + i] - tmp[8 + i]); const int b0 = a0 + a1; // 16b const int b1 = a3 + a2; const int b2 = a3 - a2; const int b3 = a0 - a1; out[ 0 + i] = b0 >> 1; // 15b out[ 4 + i] = b1 >> 1; out[ 8 + i] = b2 >> 1; out[12 + i] = b3 >> 1; } } #undef MUL #undef STORE //------------------------------------------------------------------------------ // Intra predictions #define DST(x, y) dst[(x) + (y) * BPS] static WEBP_INLINE void Fill(uint8_t* dst, int value, int size) { int j; for (j = 0; j < size; ++j) { memset(dst + j * BPS, value, size); } } static WEBP_INLINE void VerticalPred(uint8_t* dst, const uint8_t* top, int size) { int j; if (top) { for (j = 0; j < size; ++j) memcpy(dst + j * BPS, top, size); } else { Fill(dst, 127, size); } } static WEBP_INLINE void HorizontalPred(uint8_t* dst, const uint8_t* left, int size) { if (left) { int j; for (j = 0; j < size; ++j) { memset(dst + j * BPS, left[j], size); } } else { Fill(dst, 129, size); } } static WEBP_INLINE void TrueMotion(uint8_t* dst, const uint8_t* left, const uint8_t* top, int size) { int y; if (left) { if (top) { const uint8_t* const clip = clip1 + 255 - left[-1]; for (y = 0; y < size; ++y) { const uint8_t* const clip_table = clip + left[y]; int x; for (x = 0; x < size; ++x) { dst[x] = clip_table[top[x]]; } dst += BPS; } } else { HorizontalPred(dst, left, size); } } else { // true motion without left samples (hence: with default 129 value) // is equivalent to VE prediction where you just copy the top samples. // Note that if top samples are not available, the default value is // then 129, and not 127 as in the VerticalPred case. if (top) { VerticalPred(dst, top, size); } else { Fill(dst, 129, size); } } } static WEBP_INLINE void DCMode(uint8_t* dst, const uint8_t* left, const uint8_t* top, int size, int round, int shift) { int DC = 0; int j; if (top) { for (j = 0; j < size; ++j) DC += top[j]; if (left) { // top and left present for (j = 0; j < size; ++j) DC += left[j]; } else { // top, but no left DC += DC; } DC = (DC + round) >> shift; } else if (left) { // left but no top for (j = 0; j < size; ++j) DC += left[j]; DC += DC; DC = (DC + round) >> shift; } else { // no top, no left, nothing. DC = 0x80; } Fill(dst, DC, size); } //------------------------------------------------------------------------------ // Chroma 8x8 prediction (paragraph 12.2) static void IntraChromaPreds(uint8_t* dst, const uint8_t* left, const uint8_t* top) { // U block DCMode(C8DC8 + dst, left, top, 8, 8, 4); VerticalPred(C8VE8 + dst, top, 8); HorizontalPred(C8HE8 + dst, left, 8); TrueMotion(C8TM8 + dst, left, top, 8); // V block dst += 8; if (top) top += 8; if (left) left += 16; DCMode(C8DC8 + dst, left, top, 8, 8, 4); VerticalPred(C8VE8 + dst, top, 8); HorizontalPred(C8HE8 + dst, left, 8); TrueMotion(C8TM8 + dst, left, top, 8); } //------------------------------------------------------------------------------ // luma 16x16 prediction (paragraph 12.3) static void Intra16Preds(uint8_t* dst, const uint8_t* left, const uint8_t* top) { DCMode(I16DC16 + dst, left, top, 16, 16, 5); VerticalPred(I16VE16 + dst, top, 16); HorizontalPred(I16HE16 + dst, left, 16); TrueMotion(I16TM16 + dst, left, top, 16); } //------------------------------------------------------------------------------ // luma 4x4 prediction #define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2) #define AVG2(a, b) (((a) + (b) + 1) >> 1) static void VE4(uint8_t* dst, const uint8_t* top) { // vertical const uint8_t vals[4] = { AVG3(top[-1], top[0], top[1]), AVG3(top[ 0], top[1], top[2]), AVG3(top[ 1], top[2], top[3]), AVG3(top[ 2], top[3], top[4]) }; int i; for (i = 0; i < 4; ++i) { memcpy(dst + i * BPS, vals, 4); } } static void HE4(uint8_t* dst, const uint8_t* top) { // horizontal const int X = top[-1]; const int I = top[-2]; const int J = top[-3]; const int K = top[-4]; const int L = top[-5]; *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(X, I, J); *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(I, J, K); *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(J, K, L); *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(K, L, L); } static void DC4(uint8_t* dst, const uint8_t* top) { uint32_t dc = 4; int i; for (i = 0; i < 4; ++i) dc += top[i] + top[-5 + i]; Fill(dst, dc >> 3, 4); } static void RD4(uint8_t* dst, const uint8_t* top) { const int X = top[-1]; const int I = top[-2]; const int J = top[-3]; const int K = top[-4]; const int L = top[-5]; const int A = top[0]; const int B = top[1]; const int C = top[2]; const int D = top[3]; DST(0, 3) = AVG3(J, K, L); DST(0, 2) = DST(1, 3) = AVG3(I, J, K); DST(0, 1) = DST(1, 2) = DST(2, 3) = AVG3(X, I, J); DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I); DST(1, 0) = DST(2, 1) = DST(3, 2) = AVG3(B, A, X); DST(2, 0) = DST(3, 1) = AVG3(C, B, A); DST(3, 0) = AVG3(D, C, B); } static void LD4(uint8_t* dst, const uint8_t* top) { const int A = top[0]; const int B = top[1]; const int C = top[2]; const int D = top[3]; const int E = top[4]; const int F = top[5]; const int G = top[6]; const int H = top[7]; DST(0, 0) = AVG3(A, B, C); DST(1, 0) = DST(0, 1) = AVG3(B, C, D); DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E); DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F); DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G); DST(3, 2) = DST(2, 3) = AVG3(F, G, H); DST(3, 3) = AVG3(G, H, H); } static void VR4(uint8_t* dst, const uint8_t* top) { const int X = top[-1]; const int I = top[-2]; const int J = top[-3]; const int K = top[-4]; const int A = top[0]; const int B = top[1]; const int C = top[2]; const int D = top[3]; DST(0, 0) = DST(1, 2) = AVG2(X, A); DST(1, 0) = DST(2, 2) = AVG2(A, B); DST(2, 0) = DST(3, 2) = AVG2(B, C); DST(3, 0) = AVG2(C, D); DST(0, 3) = AVG3(K, J, I); DST(0, 2) = AVG3(J, I, X); DST(0, 1) = DST(1, 3) = AVG3(I, X, A); DST(1, 1) = DST(2, 3) = AVG3(X, A, B); DST(2, 1) = DST(3, 3) = AVG3(A, B, C); DST(3, 1) = AVG3(B, C, D); } static void VL4(uint8_t* dst, const uint8_t* top) { const int A = top[0]; const int B = top[1]; const int C = top[2]; const int D = top[3]; const int E = top[4]; const int F = top[5]; const int G = top[6]; const int H = top[7]; DST(0, 0) = AVG2(A, B); DST(1, 0) = DST(0, 2) = AVG2(B, C); DST(2, 0) = DST(1, 2) = AVG2(C, D); DST(3, 0) = DST(2, 2) = AVG2(D, E); DST(0, 1) = AVG3(A, B, C); DST(1, 1) = DST(0, 3) = AVG3(B, C, D); DST(2, 1) = DST(1, 3) = AVG3(C, D, E); DST(3, 1) = DST(2, 3) = AVG3(D, E, F); DST(3, 2) = AVG3(E, F, G); DST(3, 3) = AVG3(F, G, H); } static void HU4(uint8_t* dst, const uint8_t* top) { const int I = top[-2]; const int J = top[-3]; const int K = top[-4]; const int L = top[-5]; DST(0, 0) = AVG2(I, J); DST(2, 0) = DST(0, 1) = AVG2(J, K); DST(2, 1) = DST(0, 2) = AVG2(K, L); DST(1, 0) = AVG3(I, J, K); DST(3, 0) = DST(1, 1) = AVG3(J, K, L); DST(3, 1) = DST(1, 2) = AVG3(K, L, L); DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L; } static void HD4(uint8_t* dst, const uint8_t* top) { const int X = top[-1]; const int I = top[-2]; const int J = top[-3]; const int K = top[-4]; const int L = top[-5]; const int A = top[0]; const int B = top[1]; const int C = top[2]; DST(0, 0) = DST(2, 1) = AVG2(I, X); DST(0, 1) = DST(2, 2) = AVG2(J, I); DST(0, 2) = DST(2, 3) = AVG2(K, J); DST(0, 3) = AVG2(L, K); DST(3, 0) = AVG3(A, B, C); DST(2, 0) = AVG3(X, A, B); DST(1, 0) = DST(3, 1) = AVG3(I, X, A); DST(1, 1) = DST(3, 2) = AVG3(J, I, X); DST(1, 2) = DST(3, 3) = AVG3(K, J, I); DST(1, 3) = AVG3(L, K, J); } static void TM4(uint8_t* dst, const uint8_t* top) { int x, y; const uint8_t* const clip = clip1 + 255 - top[-1]; for (y = 0; y < 4; ++y) { const uint8_t* const clip_table = clip + top[-2 - y]; for (x = 0; x < 4; ++x) { dst[x] = clip_table[top[x]]; } dst += BPS; } } #undef DST #undef AVG3 #undef AVG2 // Left samples are top[-5 .. -2], top_left is top[-1], top are // located at top[0..3], and top right is top[4..7] static void Intra4Preds(uint8_t* dst, const uint8_t* top) { DC4(I4DC4 + dst, top); TM4(I4TM4 + dst, top); VE4(I4VE4 + dst, top); HE4(I4HE4 + dst, top); RD4(I4RD4 + dst, top); VR4(I4VR4 + dst, top); LD4(I4LD4 + dst, top); VL4(I4VL4 + dst, top); HD4(I4HD4 + dst, top); HU4(I4HU4 + dst, top); } //------------------------------------------------------------------------------ // Metric static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b, int w, int h) { int count = 0; int y, x; for (y = 0; y < h; ++y) { for (x = 0; x < w; ++x) { const int diff = (int)a[x] - b[x]; count += diff * diff; } a += BPS; b += BPS; } return count; } static int SSE16x16(const uint8_t* a, const uint8_t* b) { return GetSSE(a, b, 16, 16); } static int SSE16x8(const uint8_t* a, const uint8_t* b) { return GetSSE(a, b, 16, 8); } static int SSE8x8(const uint8_t* a, const uint8_t* b) { return GetSSE(a, b, 8, 8); } static int SSE4x4(const uint8_t* a, const uint8_t* b) { return GetSSE(a, b, 4, 4); } //------------------------------------------------------------------------------ // Texture distortion // // We try to match the spectral content (weighted) between source and // reconstructed samples. // Hadamard transform // Returns the weighted sum of the absolute value of transformed coefficients. static int TTransform(const uint8_t* in, const uint16_t* w) { int sum = 0; int tmp[16]; int i; // horizontal pass for (i = 0; i < 4; ++i, in += BPS) { const int a0 = in[0] + in[2]; const int a1 = in[1] + in[3]; const int a2 = in[1] - in[3]; const int a3 = in[0] - in[2]; tmp[0 + i * 4] = a0 + a1; tmp[1 + i * 4] = a3 + a2; tmp[2 + i * 4] = a3 - a2; tmp[3 + i * 4] = a0 - a1; } // vertical pass for (i = 0; i < 4; ++i, ++w) { const int a0 = tmp[0 + i] + tmp[8 + i]; const int a1 = tmp[4 + i] + tmp[12+ i]; const int a2 = tmp[4 + i] - tmp[12+ i]; const int a3 = tmp[0 + i] - tmp[8 + i]; const int b0 = a0 + a1; const int b1 = a3 + a2; const int b2 = a3 - a2; const int b3 = a0 - a1; sum += w[ 0] * abs(b0); sum += w[ 4] * abs(b1); sum += w[ 8] * abs(b2); sum += w[12] * abs(b3); } return sum; } static int Disto4x4(const uint8_t* const a, const uint8_t* const b, const uint16_t* const w) { const int sum1 = TTransform(a, w); const int sum2 = TTransform(b, w); return abs(sum2 - sum1) >> 5; } static int Disto16x16(const uint8_t* const a, const uint8_t* const b, const uint16_t* const w) { int D = 0; int x, y; for (y = 0; y < 16 * BPS; y += 4 * BPS) { for (x = 0; x < 16; x += 4) { D += Disto4x4(a + x + y, b + x + y, w); } } return D; } //------------------------------------------------------------------------------ // Quantization // static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; // Simple quantization static int QuantizeBlock(int16_t in[16], int16_t out[16], int n, const VP8Matrix* const mtx) { int last = -1; for (; n < 16; ++n) { const int j = kZigzag[n]; const int sign = (in[j] < 0); const int coeff = (sign ? -in[j] : in[j]) + mtx->sharpen_[j]; if (coeff > mtx->zthresh_[j]) { const int Q = mtx->q_[j]; const int iQ = mtx->iq_[j]; const int B = mtx->bias_[j]; out[n] = QUANTDIV(coeff, iQ, B); if (out[n] > MAX_LEVEL) out[n] = MAX_LEVEL; if (sign) out[n] = -out[n]; in[j] = out[n] * Q; if (out[n]) last = n; } else { out[n] = 0; in[j] = 0; } } return (last >= 0); } static int QuantizeBlockWHT(int16_t in[16], int16_t out[16], const VP8Matrix* const mtx) { int n, last = -1; for (n = 0; n < 16; ++n) { const int j = kZigzag[n]; const int sign = (in[j] < 0); const int coeff = sign ? -in[j] : in[j]; assert(mtx->sharpen_[j] == 0); if (coeff > mtx->zthresh_[j]) { const int Q = mtx->q_[j]; const int iQ = mtx->iq_[j]; const int B = mtx->bias_[j]; out[n] = QUANTDIV(coeff, iQ, B); if (out[n] > MAX_LEVEL) out[n] = MAX_LEVEL; if (sign) out[n] = -out[n]; in[j] = out[n] * Q; if (out[n]) last = n; } else { out[n] = 0; in[j] = 0; } } return (last >= 0); } //------------------------------------------------------------------------------ // Block copy static WEBP_INLINE void Copy(const uint8_t* src, uint8_t* dst, int size) { int y; for (y = 0; y < size; ++y) { memcpy(dst, src, size); src += BPS; dst += BPS; } } static void Copy4x4(const uint8_t* src, uint8_t* dst) { Copy(src, dst, 4); } //------------------------------------------------------------------------------ // Initialization // Speed-critical function pointers. We have to initialize them to the default // implementations within VP8EncDspInit(). VP8CHisto VP8CollectHistogram; VP8Idct VP8ITransform; VP8Fdct VP8FTransform; VP8WHT VP8ITransformWHT; VP8WHT VP8FTransformWHT; VP8Intra4Preds VP8EncPredLuma4; VP8IntraPreds VP8EncPredLuma16; VP8IntraPreds VP8EncPredChroma8; VP8Metric VP8SSE16x16; VP8Metric VP8SSE8x8; VP8Metric VP8SSE16x8; VP8Metric VP8SSE4x4; VP8WMetric VP8TDisto4x4; VP8WMetric VP8TDisto16x16; VP8QuantizeBlock VP8EncQuantizeBlock; VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT; VP8BlockCopy VP8Copy4x4; extern void VP8EncDspInitSSE2(void); extern void VP8EncDspInitNEON(void); void VP8EncDspInit(void) { InitTables(); // default C implementations VP8CollectHistogram = CollectHistogram; VP8ITransform = ITransform; VP8FTransform = FTransform; VP8ITransformWHT = ITransformWHT; VP8FTransformWHT = FTransformWHT; VP8EncPredLuma4 = Intra4Preds; VP8EncPredLuma16 = Intra16Preds; VP8EncPredChroma8 = IntraChromaPreds; VP8SSE16x16 = SSE16x16; VP8SSE8x8 = SSE8x8; VP8SSE16x8 = SSE16x8; VP8SSE4x4 = SSE4x4; VP8TDisto4x4 = Disto4x4; VP8TDisto16x16 = Disto16x16; VP8EncQuantizeBlock = QuantizeBlock; VP8EncQuantizeBlockWHT = QuantizeBlockWHT; VP8Copy4x4 = Copy4x4; // If defined, use CPUInfo() to overwrite some pointers with faster versions. if (VP8GetCPUInfo) { #if defined(WEBP_USE_SSE2) if (VP8GetCPUInfo(kSSE2)) { VP8EncDspInitSSE2(); } #elif defined(WEBP_USE_NEON) if (VP8GetCPUInfo(kNEON)) { VP8EncDspInitNEON(); } #endif } } libwebp-0.4.0/src/dsp/enc_sse2.c0000644000014400001440000011511012255002107013262 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // SSE2 version of speed-critical encoding functions. // // Author: Christian Duvivier (cduvivier@google.com) #include "./dsp.h" #if defined(WEBP_USE_SSE2) #include // for abs() #include #include "../enc/vp8enci.h" //------------------------------------------------------------------------------ // Quite useful macro for debugging. Left here for convenience. #if 0 #include static void PrintReg(const __m128i r, const char* const name, int size) { int n; union { __m128i r; uint8_t i8[16]; uint16_t i16[8]; uint32_t i32[4]; uint64_t i64[2]; } tmp; tmp.r = r; printf("%s\t: ", name); if (size == 8) { for (n = 0; n < 16; ++n) printf("%.2x ", tmp.i8[n]); } else if (size == 16) { for (n = 0; n < 8; ++n) printf("%.4x ", tmp.i16[n]); } else if (size == 32) { for (n = 0; n < 4; ++n) printf("%.8x ", tmp.i32[n]); } else { for (n = 0; n < 2; ++n) printf("%.16lx ", tmp.i64[n]); } printf("\n"); } #endif //------------------------------------------------------------------------------ // Compute susceptibility based on DCT-coeff histograms: // the higher, the "easier" the macroblock is to compress. static void CollectHistogramSSE2(const uint8_t* ref, const uint8_t* pred, int start_block, int end_block, VP8Histogram* const histo) { const __m128i max_coeff_thresh = _mm_set1_epi16(MAX_COEFF_THRESH); int j; for (j = start_block; j < end_block; ++j) { int16_t out[16]; int k; VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out); // Convert coefficients to bin (within out[]). { // Load. const __m128i out0 = _mm_loadu_si128((__m128i*)&out[0]); const __m128i out1 = _mm_loadu_si128((__m128i*)&out[8]); // sign(out) = out >> 15 (0x0000 if positive, 0xffff if negative) const __m128i sign0 = _mm_srai_epi16(out0, 15); const __m128i sign1 = _mm_srai_epi16(out1, 15); // abs(out) = (out ^ sign) - sign const __m128i xor0 = _mm_xor_si128(out0, sign0); const __m128i xor1 = _mm_xor_si128(out1, sign1); const __m128i abs0 = _mm_sub_epi16(xor0, sign0); const __m128i abs1 = _mm_sub_epi16(xor1, sign1); // v = abs(out) >> 3 const __m128i v0 = _mm_srai_epi16(abs0, 3); const __m128i v1 = _mm_srai_epi16(abs1, 3); // bin = min(v, MAX_COEFF_THRESH) const __m128i bin0 = _mm_min_epi16(v0, max_coeff_thresh); const __m128i bin1 = _mm_min_epi16(v1, max_coeff_thresh); // Store. _mm_storeu_si128((__m128i*)&out[0], bin0); _mm_storeu_si128((__m128i*)&out[8], bin1); } // Convert coefficients to bin. for (k = 0; k < 16; ++k) { histo->distribution[out[k]]++; } } } //------------------------------------------------------------------------------ // Transforms (Paragraph 14.4) // Does one or two inverse transforms. static void ITransformSSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst, int do_two) { // This implementation makes use of 16-bit fixed point versions of two // multiply constants: // K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16 // K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16 // // To be able to use signed 16-bit integers, we use the following trick to // have constants within range: // - Associated constants are obtained by subtracting the 16-bit fixed point // version of one: // k = K - (1 << 16) => K = k + (1 << 16) // K1 = 85267 => k1 = 20091 // K2 = 35468 => k2 = -30068 // - The multiplication of a variable by a constant become the sum of the // variable and the multiplication of that variable by the associated // constant: // (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x const __m128i k1 = _mm_set1_epi16(20091); const __m128i k2 = _mm_set1_epi16(-30068); __m128i T0, T1, T2, T3; // Load and concatenate the transform coefficients (we'll do two inverse // transforms in parallel). In the case of only one inverse transform, the // second half of the vectors will just contain random value we'll never // use nor store. __m128i in0, in1, in2, in3; { in0 = _mm_loadl_epi64((__m128i*)&in[0]); in1 = _mm_loadl_epi64((__m128i*)&in[4]); in2 = _mm_loadl_epi64((__m128i*)&in[8]); in3 = _mm_loadl_epi64((__m128i*)&in[12]); // a00 a10 a20 a30 x x x x // a01 a11 a21 a31 x x x x // a02 a12 a22 a32 x x x x // a03 a13 a23 a33 x x x x if (do_two) { const __m128i inB0 = _mm_loadl_epi64((__m128i*)&in[16]); const __m128i inB1 = _mm_loadl_epi64((__m128i*)&in[20]); const __m128i inB2 = _mm_loadl_epi64((__m128i*)&in[24]); const __m128i inB3 = _mm_loadl_epi64((__m128i*)&in[28]); in0 = _mm_unpacklo_epi64(in0, inB0); in1 = _mm_unpacklo_epi64(in1, inB1); in2 = _mm_unpacklo_epi64(in2, inB2); in3 = _mm_unpacklo_epi64(in3, inB3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } } // Vertical pass and subsequent transpose. { // First pass, c and d calculations are longer because of the "trick" // multiplications. const __m128i a = _mm_add_epi16(in0, in2); const __m128i b = _mm_sub_epi16(in0, in2); // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3 const __m128i c1 = _mm_mulhi_epi16(in1, k2); const __m128i c2 = _mm_mulhi_epi16(in3, k1); const __m128i c3 = _mm_sub_epi16(in1, in3); const __m128i c4 = _mm_sub_epi16(c1, c2); const __m128i c = _mm_add_epi16(c3, c4); // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3 const __m128i d1 = _mm_mulhi_epi16(in1, k1); const __m128i d2 = _mm_mulhi_epi16(in3, k2); const __m128i d3 = _mm_add_epi16(in1, in3); const __m128i d4 = _mm_add_epi16(d1, d2); const __m128i d = _mm_add_epi16(d3, d4); // Second pass. const __m128i tmp0 = _mm_add_epi16(a, d); const __m128i tmp1 = _mm_add_epi16(b, c); const __m128i tmp2 = _mm_sub_epi16(b, c); const __m128i tmp3 = _mm_sub_epi16(a, d); // Transpose the two 4x4. // a00 a01 a02 a03 b00 b01 b02 b03 // a10 a11 a12 a13 b10 b11 b12 b13 // a20 a21 a22 a23 b20 b21 b22 b23 // a30 a31 a32 a33 b30 b31 b32 b33 const __m128i transpose0_0 = _mm_unpacklo_epi16(tmp0, tmp1); const __m128i transpose0_1 = _mm_unpacklo_epi16(tmp2, tmp3); const __m128i transpose0_2 = _mm_unpackhi_epi16(tmp0, tmp1); const __m128i transpose0_3 = _mm_unpackhi_epi16(tmp2, tmp3); // a00 a10 a01 a11 a02 a12 a03 a13 // a20 a30 a21 a31 a22 a32 a23 a33 // b00 b10 b01 b11 b02 b12 b03 b13 // b20 b30 b21 b31 b22 b32 b23 b33 const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1); const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3); const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1); const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3); // a00 a10 a20 a30 a01 a11 a21 a31 // b00 b10 b20 b30 b01 b11 b21 b31 // a02 a12 a22 a32 a03 a13 a23 a33 // b02 b12 a22 b32 b03 b13 b23 b33 T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } // Horizontal pass and subsequent transpose. { // First pass, c and d calculations are longer because of the "trick" // multiplications. const __m128i four = _mm_set1_epi16(4); const __m128i dc = _mm_add_epi16(T0, four); const __m128i a = _mm_add_epi16(dc, T2); const __m128i b = _mm_sub_epi16(dc, T2); // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3 const __m128i c1 = _mm_mulhi_epi16(T1, k2); const __m128i c2 = _mm_mulhi_epi16(T3, k1); const __m128i c3 = _mm_sub_epi16(T1, T3); const __m128i c4 = _mm_sub_epi16(c1, c2); const __m128i c = _mm_add_epi16(c3, c4); // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3 const __m128i d1 = _mm_mulhi_epi16(T1, k1); const __m128i d2 = _mm_mulhi_epi16(T3, k2); const __m128i d3 = _mm_add_epi16(T1, T3); const __m128i d4 = _mm_add_epi16(d1, d2); const __m128i d = _mm_add_epi16(d3, d4); // Second pass. const __m128i tmp0 = _mm_add_epi16(a, d); const __m128i tmp1 = _mm_add_epi16(b, c); const __m128i tmp2 = _mm_sub_epi16(b, c); const __m128i tmp3 = _mm_sub_epi16(a, d); const __m128i shifted0 = _mm_srai_epi16(tmp0, 3); const __m128i shifted1 = _mm_srai_epi16(tmp1, 3); const __m128i shifted2 = _mm_srai_epi16(tmp2, 3); const __m128i shifted3 = _mm_srai_epi16(tmp3, 3); // Transpose the two 4x4. // a00 a01 a02 a03 b00 b01 b02 b03 // a10 a11 a12 a13 b10 b11 b12 b13 // a20 a21 a22 a23 b20 b21 b22 b23 // a30 a31 a32 a33 b30 b31 b32 b33 const __m128i transpose0_0 = _mm_unpacklo_epi16(shifted0, shifted1); const __m128i transpose0_1 = _mm_unpacklo_epi16(shifted2, shifted3); const __m128i transpose0_2 = _mm_unpackhi_epi16(shifted0, shifted1); const __m128i transpose0_3 = _mm_unpackhi_epi16(shifted2, shifted3); // a00 a10 a01 a11 a02 a12 a03 a13 // a20 a30 a21 a31 a22 a32 a23 a33 // b00 b10 b01 b11 b02 b12 b03 b13 // b20 b30 b21 b31 b22 b32 b23 b33 const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1); const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3); const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1); const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3); // a00 a10 a20 a30 a01 a11 a21 a31 // b00 b10 b20 b30 b01 b11 b21 b31 // a02 a12 a22 a32 a03 a13 a23 a33 // b02 b12 a22 b32 b03 b13 b23 b33 T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } // Add inverse transform to 'ref' and store. { const __m128i zero = _mm_setzero_si128(); // Load the reference(s). __m128i ref0, ref1, ref2, ref3; if (do_two) { // Load eight bytes/pixels per line. ref0 = _mm_loadl_epi64((__m128i*)&ref[0 * BPS]); ref1 = _mm_loadl_epi64((__m128i*)&ref[1 * BPS]); ref2 = _mm_loadl_epi64((__m128i*)&ref[2 * BPS]); ref3 = _mm_loadl_epi64((__m128i*)&ref[3 * BPS]); } else { // Load four bytes/pixels per line. ref0 = _mm_cvtsi32_si128(*(int*)&ref[0 * BPS]); ref1 = _mm_cvtsi32_si128(*(int*)&ref[1 * BPS]); ref2 = _mm_cvtsi32_si128(*(int*)&ref[2 * BPS]); ref3 = _mm_cvtsi32_si128(*(int*)&ref[3 * BPS]); } // Convert to 16b. ref0 = _mm_unpacklo_epi8(ref0, zero); ref1 = _mm_unpacklo_epi8(ref1, zero); ref2 = _mm_unpacklo_epi8(ref2, zero); ref3 = _mm_unpacklo_epi8(ref3, zero); // Add the inverse transform(s). ref0 = _mm_add_epi16(ref0, T0); ref1 = _mm_add_epi16(ref1, T1); ref2 = _mm_add_epi16(ref2, T2); ref3 = _mm_add_epi16(ref3, T3); // Unsigned saturate to 8b. ref0 = _mm_packus_epi16(ref0, ref0); ref1 = _mm_packus_epi16(ref1, ref1); ref2 = _mm_packus_epi16(ref2, ref2); ref3 = _mm_packus_epi16(ref3, ref3); // Store the results. if (do_two) { // Store eight bytes/pixels per line. _mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0); _mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1); _mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2); _mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3); } else { // Store four bytes/pixels per line. *((int32_t *)&dst[0 * BPS]) = _mm_cvtsi128_si32(ref0); *((int32_t *)&dst[1 * BPS]) = _mm_cvtsi128_si32(ref1); *((int32_t *)&dst[2 * BPS]) = _mm_cvtsi128_si32(ref2); *((int32_t *)&dst[3 * BPS]) = _mm_cvtsi128_si32(ref3); } } } static void FTransformSSE2(const uint8_t* src, const uint8_t* ref, int16_t* out) { const __m128i zero = _mm_setzero_si128(); const __m128i seven = _mm_set1_epi16(7); const __m128i k937 = _mm_set1_epi32(937); const __m128i k1812 = _mm_set1_epi32(1812); const __m128i k51000 = _mm_set1_epi32(51000); const __m128i k12000_plus_one = _mm_set1_epi32(12000 + (1 << 16)); const __m128i k5352_2217 = _mm_set_epi16(5352, 2217, 5352, 2217, 5352, 2217, 5352, 2217); const __m128i k2217_5352 = _mm_set_epi16(2217, -5352, 2217, -5352, 2217, -5352, 2217, -5352); const __m128i k88p = _mm_set_epi16(8, 8, 8, 8, 8, 8, 8, 8); const __m128i k88m = _mm_set_epi16(-8, 8, -8, 8, -8, 8, -8, 8); const __m128i k5352_2217p = _mm_set_epi16(2217, 5352, 2217, 5352, 2217, 5352, 2217, 5352); const __m128i k5352_2217m = _mm_set_epi16(-5352, 2217, -5352, 2217, -5352, 2217, -5352, 2217); __m128i v01, v32; // Difference between src and ref and initial transpose. { // Load src and convert to 16b. const __m128i src0 = _mm_loadl_epi64((__m128i*)&src[0 * BPS]); const __m128i src1 = _mm_loadl_epi64((__m128i*)&src[1 * BPS]); const __m128i src2 = _mm_loadl_epi64((__m128i*)&src[2 * BPS]); const __m128i src3 = _mm_loadl_epi64((__m128i*)&src[3 * BPS]); const __m128i src_0 = _mm_unpacklo_epi8(src0, zero); const __m128i src_1 = _mm_unpacklo_epi8(src1, zero); const __m128i src_2 = _mm_unpacklo_epi8(src2, zero); const __m128i src_3 = _mm_unpacklo_epi8(src3, zero); // Load ref and convert to 16b. const __m128i ref0 = _mm_loadl_epi64((__m128i*)&ref[0 * BPS]); const __m128i ref1 = _mm_loadl_epi64((__m128i*)&ref[1 * BPS]); const __m128i ref2 = _mm_loadl_epi64((__m128i*)&ref[2 * BPS]); const __m128i ref3 = _mm_loadl_epi64((__m128i*)&ref[3 * BPS]); const __m128i ref_0 = _mm_unpacklo_epi8(ref0, zero); const __m128i ref_1 = _mm_unpacklo_epi8(ref1, zero); const __m128i ref_2 = _mm_unpacklo_epi8(ref2, zero); const __m128i ref_3 = _mm_unpacklo_epi8(ref3, zero); // Compute difference. -> 00 01 02 03 00 00 00 00 const __m128i diff0 = _mm_sub_epi16(src_0, ref_0); const __m128i diff1 = _mm_sub_epi16(src_1, ref_1); const __m128i diff2 = _mm_sub_epi16(src_2, ref_2); const __m128i diff3 = _mm_sub_epi16(src_3, ref_3); // Unpack and shuffle // 00 01 02 03 0 0 0 0 // 10 11 12 13 0 0 0 0 // 20 21 22 23 0 0 0 0 // 30 31 32 33 0 0 0 0 const __m128i shuf01 = _mm_unpacklo_epi32(diff0, diff1); const __m128i shuf23 = _mm_unpacklo_epi32(diff2, diff3); // 00 01 10 11 02 03 12 13 // 20 21 30 31 22 23 32 33 const __m128i shuf01_p = _mm_shufflehi_epi16(shuf01, _MM_SHUFFLE(2, 3, 0, 1)); const __m128i shuf23_p = _mm_shufflehi_epi16(shuf23, _MM_SHUFFLE(2, 3, 0, 1)); // 00 01 10 11 03 02 13 12 // 20 21 30 31 23 22 33 32 const __m128i s01 = _mm_unpacklo_epi64(shuf01_p, shuf23_p); const __m128i s32 = _mm_unpackhi_epi64(shuf01_p, shuf23_p); // 00 01 10 11 20 21 30 31 // 03 02 13 12 23 22 33 32 const __m128i a01 = _mm_add_epi16(s01, s32); const __m128i a32 = _mm_sub_epi16(s01, s32); // [d0 + d3 | d1 + d2 | ...] = [a0 a1 | a0' a1' | ... ] // [d0 - d3 | d1 - d2 | ...] = [a3 a2 | a3' a2' | ... ] const __m128i tmp0 = _mm_madd_epi16(a01, k88p); // [ (a0 + a1) << 3, ... ] const __m128i tmp2 = _mm_madd_epi16(a01, k88m); // [ (a0 - a1) << 3, ... ] const __m128i tmp1_1 = _mm_madd_epi16(a32, k5352_2217p); const __m128i tmp3_1 = _mm_madd_epi16(a32, k5352_2217m); const __m128i tmp1_2 = _mm_add_epi32(tmp1_1, k1812); const __m128i tmp3_2 = _mm_add_epi32(tmp3_1, k937); const __m128i tmp1 = _mm_srai_epi32(tmp1_2, 9); const __m128i tmp3 = _mm_srai_epi32(tmp3_2, 9); const __m128i s03 = _mm_packs_epi32(tmp0, tmp2); const __m128i s12 = _mm_packs_epi32(tmp1, tmp3); const __m128i s_lo = _mm_unpacklo_epi16(s03, s12); // 0 1 0 1 0 1... const __m128i s_hi = _mm_unpackhi_epi16(s03, s12); // 2 3 2 3 2 3 const __m128i v23 = _mm_unpackhi_epi32(s_lo, s_hi); v01 = _mm_unpacklo_epi32(s_lo, s_hi); v32 = _mm_shuffle_epi32(v23, _MM_SHUFFLE(1, 0, 3, 2)); // 3 2 3 2 3 2.. } // Second pass { // Same operations are done on the (0,3) and (1,2) pairs. // a0 = v0 + v3 // a1 = v1 + v2 // a3 = v0 - v3 // a2 = v1 - v2 const __m128i a01 = _mm_add_epi16(v01, v32); const __m128i a32 = _mm_sub_epi16(v01, v32); const __m128i a11 = _mm_unpackhi_epi64(a01, a01); const __m128i a22 = _mm_unpackhi_epi64(a32, a32); const __m128i a01_plus_7 = _mm_add_epi16(a01, seven); // d0 = (a0 + a1 + 7) >> 4; // d2 = (a0 - a1 + 7) >> 4; const __m128i c0 = _mm_add_epi16(a01_plus_7, a11); const __m128i c2 = _mm_sub_epi16(a01_plus_7, a11); const __m128i d0 = _mm_srai_epi16(c0, 4); const __m128i d2 = _mm_srai_epi16(c2, 4); // f1 = ((b3 * 5352 + b2 * 2217 + 12000) >> 16) // f3 = ((b3 * 2217 - b2 * 5352 + 51000) >> 16) const __m128i b23 = _mm_unpacklo_epi16(a22, a32); const __m128i c1 = _mm_madd_epi16(b23, k5352_2217); const __m128i c3 = _mm_madd_epi16(b23, k2217_5352); const __m128i d1 = _mm_add_epi32(c1, k12000_plus_one); const __m128i d3 = _mm_add_epi32(c3, k51000); const __m128i e1 = _mm_srai_epi32(d1, 16); const __m128i e3 = _mm_srai_epi32(d3, 16); const __m128i f1 = _mm_packs_epi32(e1, e1); const __m128i f3 = _mm_packs_epi32(e3, e3); // f1 = f1 + (a3 != 0); // The compare will return (0xffff, 0) for (==0, !=0). To turn that into the // desired (0, 1), we add one earlier through k12000_plus_one. // -> f1 = f1 + 1 - (a3 == 0) const __m128i g1 = _mm_add_epi16(f1, _mm_cmpeq_epi16(a32, zero)); _mm_storel_epi64((__m128i*)&out[ 0], d0); _mm_storel_epi64((__m128i*)&out[ 4], g1); _mm_storel_epi64((__m128i*)&out[ 8], d2); _mm_storel_epi64((__m128i*)&out[12], f3); } } static void FTransformWHTSSE2(const int16_t* in, int16_t* out) { int32_t tmp[16]; int i; for (i = 0; i < 4; ++i, in += 64) { const int a0 = (in[0 * 16] + in[2 * 16]); const int a1 = (in[1 * 16] + in[3 * 16]); const int a2 = (in[1 * 16] - in[3 * 16]); const int a3 = (in[0 * 16] - in[2 * 16]); tmp[0 + i * 4] = a0 + a1; tmp[1 + i * 4] = a3 + a2; tmp[2 + i * 4] = a3 - a2; tmp[3 + i * 4] = a0 - a1; } { const __m128i src0 = _mm_loadu_si128((__m128i*)&tmp[0]); const __m128i src1 = _mm_loadu_si128((__m128i*)&tmp[4]); const __m128i src2 = _mm_loadu_si128((__m128i*)&tmp[8]); const __m128i src3 = _mm_loadu_si128((__m128i*)&tmp[12]); const __m128i a0 = _mm_add_epi32(src0, src2); const __m128i a1 = _mm_add_epi32(src1, src3); const __m128i a2 = _mm_sub_epi32(src1, src3); const __m128i a3 = _mm_sub_epi32(src0, src2); const __m128i b0 = _mm_srai_epi32(_mm_add_epi32(a0, a1), 1); const __m128i b1 = _mm_srai_epi32(_mm_add_epi32(a3, a2), 1); const __m128i b2 = _mm_srai_epi32(_mm_sub_epi32(a3, a2), 1); const __m128i b3 = _mm_srai_epi32(_mm_sub_epi32(a0, a1), 1); const __m128i out0 = _mm_packs_epi32(b0, b1); const __m128i out1 = _mm_packs_epi32(b2, b3); _mm_storeu_si128((__m128i*)&out[0], out0); _mm_storeu_si128((__m128i*)&out[8], out1); } } //------------------------------------------------------------------------------ // Metric static int SSE_Nx4SSE2(const uint8_t* a, const uint8_t* b, int num_quads, int do_16) { const __m128i zero = _mm_setzero_si128(); __m128i sum1 = zero; __m128i sum2 = zero; while (num_quads-- > 0) { // Note: for the !do_16 case, we read 16 pixels instead of 8 but that's ok, // thanks to buffer over-allocation to that effect. const __m128i a0 = _mm_loadu_si128((__m128i*)&a[BPS * 0]); const __m128i a1 = _mm_loadu_si128((__m128i*)&a[BPS * 1]); const __m128i a2 = _mm_loadu_si128((__m128i*)&a[BPS * 2]); const __m128i a3 = _mm_loadu_si128((__m128i*)&a[BPS * 3]); const __m128i b0 = _mm_loadu_si128((__m128i*)&b[BPS * 0]); const __m128i b1 = _mm_loadu_si128((__m128i*)&b[BPS * 1]); const __m128i b2 = _mm_loadu_si128((__m128i*)&b[BPS * 2]); const __m128i b3 = _mm_loadu_si128((__m128i*)&b[BPS * 3]); // compute clip0(a-b) and clip0(b-a) const __m128i a0p = _mm_subs_epu8(a0, b0); const __m128i a0m = _mm_subs_epu8(b0, a0); const __m128i a1p = _mm_subs_epu8(a1, b1); const __m128i a1m = _mm_subs_epu8(b1, a1); const __m128i a2p = _mm_subs_epu8(a2, b2); const __m128i a2m = _mm_subs_epu8(b2, a2); const __m128i a3p = _mm_subs_epu8(a3, b3); const __m128i a3m = _mm_subs_epu8(b3, a3); // compute |a-b| with 8b arithmetic as clip0(a-b) | clip0(b-a) const __m128i diff0 = _mm_or_si128(a0p, a0m); const __m128i diff1 = _mm_or_si128(a1p, a1m); const __m128i diff2 = _mm_or_si128(a2p, a2m); const __m128i diff3 = _mm_or_si128(a3p, a3m); // unpack (only four operations, instead of eight) const __m128i low0 = _mm_unpacklo_epi8(diff0, zero); const __m128i low1 = _mm_unpacklo_epi8(diff1, zero); const __m128i low2 = _mm_unpacklo_epi8(diff2, zero); const __m128i low3 = _mm_unpacklo_epi8(diff3, zero); // multiply with self const __m128i low_madd0 = _mm_madd_epi16(low0, low0); const __m128i low_madd1 = _mm_madd_epi16(low1, low1); const __m128i low_madd2 = _mm_madd_epi16(low2, low2); const __m128i low_madd3 = _mm_madd_epi16(low3, low3); // collect in a cascading way const __m128i low_sum0 = _mm_add_epi32(low_madd0, low_madd1); const __m128i low_sum1 = _mm_add_epi32(low_madd2, low_madd3); sum1 = _mm_add_epi32(sum1, low_sum0); sum2 = _mm_add_epi32(sum2, low_sum1); if (do_16) { // if necessary, process the higher 8 bytes similarly const __m128i hi0 = _mm_unpackhi_epi8(diff0, zero); const __m128i hi1 = _mm_unpackhi_epi8(diff1, zero); const __m128i hi2 = _mm_unpackhi_epi8(diff2, zero); const __m128i hi3 = _mm_unpackhi_epi8(diff3, zero); const __m128i hi_madd0 = _mm_madd_epi16(hi0, hi0); const __m128i hi_madd1 = _mm_madd_epi16(hi1, hi1); const __m128i hi_madd2 = _mm_madd_epi16(hi2, hi2); const __m128i hi_madd3 = _mm_madd_epi16(hi3, hi3); const __m128i hi_sum0 = _mm_add_epi32(hi_madd0, hi_madd1); const __m128i hi_sum1 = _mm_add_epi32(hi_madd2, hi_madd3); sum1 = _mm_add_epi32(sum1, hi_sum0); sum2 = _mm_add_epi32(sum2, hi_sum1); } a += 4 * BPS; b += 4 * BPS; } { int32_t tmp[4]; const __m128i sum = _mm_add_epi32(sum1, sum2); _mm_storeu_si128((__m128i*)tmp, sum); return (tmp[3] + tmp[2] + tmp[1] + tmp[0]); } } static int SSE16x16SSE2(const uint8_t* a, const uint8_t* b) { return SSE_Nx4SSE2(a, b, 4, 1); } static int SSE16x8SSE2(const uint8_t* a, const uint8_t* b) { return SSE_Nx4SSE2(a, b, 2, 1); } static int SSE8x8SSE2(const uint8_t* a, const uint8_t* b) { return SSE_Nx4SSE2(a, b, 2, 0); } static int SSE4x4SSE2(const uint8_t* a, const uint8_t* b) { const __m128i zero = _mm_setzero_si128(); // Load values. Note that we read 8 pixels instead of 4, // but the a/b buffers are over-allocated to that effect. const __m128i a0 = _mm_loadl_epi64((__m128i*)&a[BPS * 0]); const __m128i a1 = _mm_loadl_epi64((__m128i*)&a[BPS * 1]); const __m128i a2 = _mm_loadl_epi64((__m128i*)&a[BPS * 2]); const __m128i a3 = _mm_loadl_epi64((__m128i*)&a[BPS * 3]); const __m128i b0 = _mm_loadl_epi64((__m128i*)&b[BPS * 0]); const __m128i b1 = _mm_loadl_epi64((__m128i*)&b[BPS * 1]); const __m128i b2 = _mm_loadl_epi64((__m128i*)&b[BPS * 2]); const __m128i b3 = _mm_loadl_epi64((__m128i*)&b[BPS * 3]); // Combine pair of lines and convert to 16b. const __m128i a01 = _mm_unpacklo_epi32(a0, a1); const __m128i a23 = _mm_unpacklo_epi32(a2, a3); const __m128i b01 = _mm_unpacklo_epi32(b0, b1); const __m128i b23 = _mm_unpacklo_epi32(b2, b3); const __m128i a01s = _mm_unpacklo_epi8(a01, zero); const __m128i a23s = _mm_unpacklo_epi8(a23, zero); const __m128i b01s = _mm_unpacklo_epi8(b01, zero); const __m128i b23s = _mm_unpacklo_epi8(b23, zero); // Compute differences; (a-b)^2 = (abs(a-b))^2 = (sat8(a-b) + sat8(b-a))^2 // TODO(cduvivier): Dissassemble and figure out why this is fastest. We don't // need absolute values, there is no need to do calculation // in 8bit as we are already in 16bit, ... Yet this is what // benchmarks the fastest! const __m128i d0 = _mm_subs_epu8(a01s, b01s); const __m128i d1 = _mm_subs_epu8(b01s, a01s); const __m128i d2 = _mm_subs_epu8(a23s, b23s); const __m128i d3 = _mm_subs_epu8(b23s, a23s); // Square and add them all together. const __m128i madd0 = _mm_madd_epi16(d0, d0); const __m128i madd1 = _mm_madd_epi16(d1, d1); const __m128i madd2 = _mm_madd_epi16(d2, d2); const __m128i madd3 = _mm_madd_epi16(d3, d3); const __m128i sum0 = _mm_add_epi32(madd0, madd1); const __m128i sum1 = _mm_add_epi32(madd2, madd3); const __m128i sum2 = _mm_add_epi32(sum0, sum1); int32_t tmp[4]; _mm_storeu_si128((__m128i*)tmp, sum2); return (tmp[3] + tmp[2] + tmp[1] + tmp[0]); } //------------------------------------------------------------------------------ // Texture distortion // // We try to match the spectral content (weighted) between source and // reconstructed samples. // Hadamard transform // Returns the difference between the weighted sum of the absolute value of // transformed coefficients. static int TTransformSSE2(const uint8_t* inA, const uint8_t* inB, const uint16_t* const w) { int32_t sum[4]; __m128i tmp_0, tmp_1, tmp_2, tmp_3; const __m128i zero = _mm_setzero_si128(); // Load, combine and transpose inputs. { const __m128i inA_0 = _mm_loadl_epi64((__m128i*)&inA[BPS * 0]); const __m128i inA_1 = _mm_loadl_epi64((__m128i*)&inA[BPS * 1]); const __m128i inA_2 = _mm_loadl_epi64((__m128i*)&inA[BPS * 2]); const __m128i inA_3 = _mm_loadl_epi64((__m128i*)&inA[BPS * 3]); const __m128i inB_0 = _mm_loadl_epi64((__m128i*)&inB[BPS * 0]); const __m128i inB_1 = _mm_loadl_epi64((__m128i*)&inB[BPS * 1]); const __m128i inB_2 = _mm_loadl_epi64((__m128i*)&inB[BPS * 2]); const __m128i inB_3 = _mm_loadl_epi64((__m128i*)&inB[BPS * 3]); // Combine inA and inB (we'll do two transforms in parallel). const __m128i inAB_0 = _mm_unpacklo_epi8(inA_0, inB_0); const __m128i inAB_1 = _mm_unpacklo_epi8(inA_1, inB_1); const __m128i inAB_2 = _mm_unpacklo_epi8(inA_2, inB_2); const __m128i inAB_3 = _mm_unpacklo_epi8(inA_3, inB_3); // a00 b00 a01 b01 a02 b03 a03 b03 0 0 0 0 0 0 0 0 // a10 b10 a11 b11 a12 b12 a13 b13 0 0 0 0 0 0 0 0 // a20 b20 a21 b21 a22 b22 a23 b23 0 0 0 0 0 0 0 0 // a30 b30 a31 b31 a32 b32 a33 b33 0 0 0 0 0 0 0 0 // Transpose the two 4x4, discarding the filling zeroes. const __m128i transpose0_0 = _mm_unpacklo_epi8(inAB_0, inAB_2); const __m128i transpose0_1 = _mm_unpacklo_epi8(inAB_1, inAB_3); // a00 a20 b00 b20 a01 a21 b01 b21 a02 a22 b02 b22 a03 a23 b03 b23 // a10 a30 b10 b30 a11 a31 b11 b31 a12 a32 b12 b32 a13 a33 b13 b33 const __m128i transpose1_0 = _mm_unpacklo_epi8(transpose0_0, transpose0_1); const __m128i transpose1_1 = _mm_unpackhi_epi8(transpose0_0, transpose0_1); // a00 a10 a20 a30 b00 b10 b20 b30 a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 a03 a13 a23 a33 b03 b13 b23 b33 // Convert to 16b. tmp_0 = _mm_unpacklo_epi8(transpose1_0, zero); tmp_1 = _mm_unpackhi_epi8(transpose1_0, zero); tmp_2 = _mm_unpacklo_epi8(transpose1_1, zero); tmp_3 = _mm_unpackhi_epi8(transpose1_1, zero); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } // Horizontal pass and subsequent transpose. { // Calculate a and b (two 4x4 at once). const __m128i a0 = _mm_add_epi16(tmp_0, tmp_2); const __m128i a1 = _mm_add_epi16(tmp_1, tmp_3); const __m128i a2 = _mm_sub_epi16(tmp_1, tmp_3); const __m128i a3 = _mm_sub_epi16(tmp_0, tmp_2); const __m128i b0 = _mm_add_epi16(a0, a1); const __m128i b1 = _mm_add_epi16(a3, a2); const __m128i b2 = _mm_sub_epi16(a3, a2); const __m128i b3 = _mm_sub_epi16(a0, a1); // a00 a01 a02 a03 b00 b01 b02 b03 // a10 a11 a12 a13 b10 b11 b12 b13 // a20 a21 a22 a23 b20 b21 b22 b23 // a30 a31 a32 a33 b30 b31 b32 b33 // Transpose the two 4x4. const __m128i transpose0_0 = _mm_unpacklo_epi16(b0, b1); const __m128i transpose0_1 = _mm_unpacklo_epi16(b2, b3); const __m128i transpose0_2 = _mm_unpackhi_epi16(b0, b1); const __m128i transpose0_3 = _mm_unpackhi_epi16(b2, b3); // a00 a10 a01 a11 a02 a12 a03 a13 // a20 a30 a21 a31 a22 a32 a23 a33 // b00 b10 b01 b11 b02 b12 b03 b13 // b20 b30 b21 b31 b22 b32 b23 b33 const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1); const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3); const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1); const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3); // a00 a10 a20 a30 a01 a11 a21 a31 // b00 b10 b20 b30 b01 b11 b21 b31 // a02 a12 a22 a32 a03 a13 a23 a33 // b02 b12 a22 b32 b03 b13 b23 b33 tmp_0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); tmp_1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); tmp_2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); tmp_3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } // Vertical pass and difference of weighted sums. { // Load all inputs. // TODO(cduvivier): Make variable declarations and allocations aligned so // we can use _mm_load_si128 instead of _mm_loadu_si128. const __m128i w_0 = _mm_loadu_si128((__m128i*)&w[0]); const __m128i w_8 = _mm_loadu_si128((__m128i*)&w[8]); // Calculate a and b (two 4x4 at once). const __m128i a0 = _mm_add_epi16(tmp_0, tmp_2); const __m128i a1 = _mm_add_epi16(tmp_1, tmp_3); const __m128i a2 = _mm_sub_epi16(tmp_1, tmp_3); const __m128i a3 = _mm_sub_epi16(tmp_0, tmp_2); const __m128i b0 = _mm_add_epi16(a0, a1); const __m128i b1 = _mm_add_epi16(a3, a2); const __m128i b2 = _mm_sub_epi16(a3, a2); const __m128i b3 = _mm_sub_epi16(a0, a1); // Separate the transforms of inA and inB. __m128i A_b0 = _mm_unpacklo_epi64(b0, b1); __m128i A_b2 = _mm_unpacklo_epi64(b2, b3); __m128i B_b0 = _mm_unpackhi_epi64(b0, b1); __m128i B_b2 = _mm_unpackhi_epi64(b2, b3); { // sign(b) = b >> 15 (0x0000 if positive, 0xffff if negative) const __m128i sign_A_b0 = _mm_srai_epi16(A_b0, 15); const __m128i sign_A_b2 = _mm_srai_epi16(A_b2, 15); const __m128i sign_B_b0 = _mm_srai_epi16(B_b0, 15); const __m128i sign_B_b2 = _mm_srai_epi16(B_b2, 15); // b = abs(b) = (b ^ sign) - sign A_b0 = _mm_xor_si128(A_b0, sign_A_b0); A_b2 = _mm_xor_si128(A_b2, sign_A_b2); B_b0 = _mm_xor_si128(B_b0, sign_B_b0); B_b2 = _mm_xor_si128(B_b2, sign_B_b2); A_b0 = _mm_sub_epi16(A_b0, sign_A_b0); A_b2 = _mm_sub_epi16(A_b2, sign_A_b2); B_b0 = _mm_sub_epi16(B_b0, sign_B_b0); B_b2 = _mm_sub_epi16(B_b2, sign_B_b2); } // weighted sums A_b0 = _mm_madd_epi16(A_b0, w_0); A_b2 = _mm_madd_epi16(A_b2, w_8); B_b0 = _mm_madd_epi16(B_b0, w_0); B_b2 = _mm_madd_epi16(B_b2, w_8); A_b0 = _mm_add_epi32(A_b0, A_b2); B_b0 = _mm_add_epi32(B_b0, B_b2); // difference of weighted sums A_b0 = _mm_sub_epi32(A_b0, B_b0); _mm_storeu_si128((__m128i*)&sum[0], A_b0); } return sum[0] + sum[1] + sum[2] + sum[3]; } static int Disto4x4SSE2(const uint8_t* const a, const uint8_t* const b, const uint16_t* const w) { const int diff_sum = TTransformSSE2(a, b, w); return abs(diff_sum) >> 5; } static int Disto16x16SSE2(const uint8_t* const a, const uint8_t* const b, const uint16_t* const w) { int D = 0; int x, y; for (y = 0; y < 16 * BPS; y += 4 * BPS) { for (x = 0; x < 16; x += 4) { D += Disto4x4SSE2(a + x + y, b + x + y, w); } } return D; } //------------------------------------------------------------------------------ // Quantization // // Simple quantization static int QuantizeBlockSSE2(int16_t in[16], int16_t out[16], int n, const VP8Matrix* const mtx) { const __m128i max_coeff_2047 = _mm_set1_epi16(MAX_LEVEL); const __m128i zero = _mm_setzero_si128(); __m128i coeff0, coeff8; __m128i out0, out8; __m128i packed_out; // Load all inputs. // TODO(cduvivier): Make variable declarations and allocations aligned so that // we can use _mm_load_si128 instead of _mm_loadu_si128. __m128i in0 = _mm_loadu_si128((__m128i*)&in[0]); __m128i in8 = _mm_loadu_si128((__m128i*)&in[8]); const __m128i sharpen0 = _mm_loadu_si128((__m128i*)&mtx->sharpen_[0]); const __m128i sharpen8 = _mm_loadu_si128((__m128i*)&mtx->sharpen_[8]); const __m128i iq0 = _mm_loadu_si128((__m128i*)&mtx->iq_[0]); const __m128i iq8 = _mm_loadu_si128((__m128i*)&mtx->iq_[8]); const __m128i bias0 = _mm_loadu_si128((__m128i*)&mtx->bias_[0]); const __m128i bias8 = _mm_loadu_si128((__m128i*)&mtx->bias_[8]); const __m128i q0 = _mm_loadu_si128((__m128i*)&mtx->q_[0]); const __m128i q8 = _mm_loadu_si128((__m128i*)&mtx->q_[8]); // sign(in) = in >> 15 (0x0000 if positive, 0xffff if negative) const __m128i sign0 = _mm_srai_epi16(in0, 15); const __m128i sign8 = _mm_srai_epi16(in8, 15); // coeff = abs(in) = (in ^ sign) - sign coeff0 = _mm_xor_si128(in0, sign0); coeff8 = _mm_xor_si128(in8, sign8); coeff0 = _mm_sub_epi16(coeff0, sign0); coeff8 = _mm_sub_epi16(coeff8, sign8); // coeff = abs(in) + sharpen coeff0 = _mm_add_epi16(coeff0, sharpen0); coeff8 = _mm_add_epi16(coeff8, sharpen8); // out = (coeff * iQ + B) >> QFIX; { // doing calculations with 32b precision (QFIX=17) // out = (coeff * iQ) __m128i coeff_iQ0H = _mm_mulhi_epu16(coeff0, iq0); __m128i coeff_iQ0L = _mm_mullo_epi16(coeff0, iq0); __m128i coeff_iQ8H = _mm_mulhi_epu16(coeff8, iq8); __m128i coeff_iQ8L = _mm_mullo_epi16(coeff8, iq8); __m128i out_00 = _mm_unpacklo_epi16(coeff_iQ0L, coeff_iQ0H); __m128i out_04 = _mm_unpackhi_epi16(coeff_iQ0L, coeff_iQ0H); __m128i out_08 = _mm_unpacklo_epi16(coeff_iQ8L, coeff_iQ8H); __m128i out_12 = _mm_unpackhi_epi16(coeff_iQ8L, coeff_iQ8H); // expand bias from 16b to 32b __m128i bias_00 = _mm_unpacklo_epi16(bias0, zero); __m128i bias_04 = _mm_unpackhi_epi16(bias0, zero); __m128i bias_08 = _mm_unpacklo_epi16(bias8, zero); __m128i bias_12 = _mm_unpackhi_epi16(bias8, zero); // out = (coeff * iQ + B) out_00 = _mm_add_epi32(out_00, bias_00); out_04 = _mm_add_epi32(out_04, bias_04); out_08 = _mm_add_epi32(out_08, bias_08); out_12 = _mm_add_epi32(out_12, bias_12); // out = (coeff * iQ + B) >> QFIX; out_00 = _mm_srai_epi32(out_00, QFIX); out_04 = _mm_srai_epi32(out_04, QFIX); out_08 = _mm_srai_epi32(out_08, QFIX); out_12 = _mm_srai_epi32(out_12, QFIX); // pack result as 16b out0 = _mm_packs_epi32(out_00, out_04); out8 = _mm_packs_epi32(out_08, out_12); // if (coeff > 2047) coeff = 2047 out0 = _mm_min_epi16(out0, max_coeff_2047); out8 = _mm_min_epi16(out8, max_coeff_2047); } // get sign back (if (sign[j]) out_n = -out_n) out0 = _mm_xor_si128(out0, sign0); out8 = _mm_xor_si128(out8, sign8); out0 = _mm_sub_epi16(out0, sign0); out8 = _mm_sub_epi16(out8, sign8); // in = out * Q in0 = _mm_mullo_epi16(out0, q0); in8 = _mm_mullo_epi16(out8, q8); _mm_storeu_si128((__m128i*)&in[0], in0); _mm_storeu_si128((__m128i*)&in[8], in8); // zigzag the output before storing it. // // The zigzag pattern can almost be reproduced with a small sequence of // shuffles. After it, we only need to swap the 7th (ending up in third // position instead of twelfth) and 8th values. { __m128i outZ0, outZ8; outZ0 = _mm_shufflehi_epi16(out0, _MM_SHUFFLE(2, 1, 3, 0)); outZ0 = _mm_shuffle_epi32 (outZ0, _MM_SHUFFLE(3, 1, 2, 0)); outZ0 = _mm_shufflehi_epi16(outZ0, _MM_SHUFFLE(3, 1, 0, 2)); outZ8 = _mm_shufflelo_epi16(out8, _MM_SHUFFLE(3, 0, 2, 1)); outZ8 = _mm_shuffle_epi32 (outZ8, _MM_SHUFFLE(3, 1, 2, 0)); outZ8 = _mm_shufflelo_epi16(outZ8, _MM_SHUFFLE(1, 3, 2, 0)); _mm_storeu_si128((__m128i*)&out[0], outZ0); _mm_storeu_si128((__m128i*)&out[8], outZ8); packed_out = _mm_packs_epi16(outZ0, outZ8); } { const int16_t outZ_12 = out[12]; const int16_t outZ_3 = out[3]; out[3] = outZ_12; out[12] = outZ_3; } // detect if all 'out' values are zeroes or not { int32_t tmp[4]; _mm_storeu_si128((__m128i*)tmp, packed_out); if (n) { tmp[0] &= ~0xff; } return (tmp[3] || tmp[2] || tmp[1] || tmp[0]); } } static int QuantizeBlockWHTSSE2(int16_t in[16], int16_t out[16], const VP8Matrix* const mtx) { return QuantizeBlockSSE2(in, out, 0, mtx); } #endif // WEBP_USE_SSE2 //------------------------------------------------------------------------------ // Entry point extern void VP8EncDspInitSSE2(void); void VP8EncDspInitSSE2(void) { #if defined(WEBP_USE_SSE2) VP8CollectHistogram = CollectHistogramSSE2; VP8EncQuantizeBlock = QuantizeBlockSSE2; VP8EncQuantizeBlockWHT = QuantizeBlockWHTSSE2; VP8ITransform = ITransformSSE2; VP8FTransform = FTransformSSE2; VP8FTransformWHT = FTransformWHTSSE2; VP8SSE16x16 = SSE16x16SSE2; VP8SSE16x8 = SSE16x8SSE2; VP8SSE8x8 = SSE8x8SSE2; VP8SSE4x4 = SSE4x4SSE2; VP8TDisto4x4 = Disto4x4SSE2; VP8TDisto16x16 = Disto16x16SSE2; #endif // WEBP_USE_SSE2 } libwebp-0.4.0/src/dsp/Makefile.in0000644000014400001440000013130712255206714013502 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ @BUILD_LIBWEBPDECODER_TRUE@am__append_1 = libwebpdspdecode.la subdir = src/dsp DIST_COMMON = $(common_HEADERS) $(noinst_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libwebpdsp_la_LIBADD = am__objects_1 = libwebpdsp_la-cpu.lo libwebpdsp_la-dec.lo \ libwebpdsp_la-dec_neon.lo libwebpdsp_la-dec_sse2.lo \ libwebpdsp_la-lossless.lo libwebpdsp_la-upsampling.lo \ libwebpdsp_la-upsampling_neon.lo \ libwebpdsp_la-upsampling_sse2.lo libwebpdsp_la-yuv.lo am__objects_2 = libwebpdsp_la-enc.lo libwebpdsp_la-enc_neon.lo \ libwebpdsp_la-enc_sse2.lo am_libwebpdsp_la_OBJECTS = $(am__objects_1) $(am__objects_2) libwebpdsp_la_OBJECTS = $(am_libwebpdsp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libwebpdsp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libwebpdsp_la_LDFLAGS) $(LDFLAGS) -o $@ libwebpdspdecode_la_LIBADD = am__libwebpdspdecode_la_SOURCES_DIST = cpu.c dec.c dec_neon.c \ dec_sse2.c dsp.h lossless.c lossless.h upsampling.c \ upsampling_neon.c upsampling_sse2.c yuv.c yuv.h am__objects_3 = libwebpdspdecode_la-cpu.lo libwebpdspdecode_la-dec.lo \ libwebpdspdecode_la-dec_neon.lo \ libwebpdspdecode_la-dec_sse2.lo \ libwebpdspdecode_la-lossless.lo \ libwebpdspdecode_la-upsampling.lo \ libwebpdspdecode_la-upsampling_neon.lo \ libwebpdspdecode_la-upsampling_sse2.lo \ libwebpdspdecode_la-yuv.lo @BUILD_LIBWEBPDECODER_TRUE@am_libwebpdspdecode_la_OBJECTS = \ @BUILD_LIBWEBPDECODER_TRUE@ $(am__objects_3) libwebpdspdecode_la_OBJECTS = $(am_libwebpdspdecode_la_OBJECTS) libwebpdspdecode_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libwebpdspdecode_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILD_LIBWEBPDECODER_TRUE@am_libwebpdspdecode_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebpdsp_la_SOURCES) $(libwebpdspdecode_la_SOURCES) DIST_SOURCES = $(libwebpdsp_la_SOURCES) \ $(am__libwebpdspdecode_la_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(commondir)" HEADERS = $(common_HEADERS) $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebpdsp.la $(am__append_1) common_HEADERS = ../webp/types.h commondir = $(includedir)/webp COMMON_SOURCES = cpu.c dec.c dec_neon.c dec_sse2.c dsp.h lossless.c \ lossless.h upsampling.c upsampling_neon.c upsampling_sse2.c \ yuv.c yuv.h ENC_SOURCES = enc.c enc_neon.c enc_sse2.c libwebpdsp_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) noinst_HEADERS = ../dec/decode_vp8.h ../webp/decode.h libwebpdsp_la_LDFLAGS = -lm libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) $(USE_SWAP_16BIT_CSP) @BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_SOURCES = $(COMMON_SOURCES) @BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_LDFLAGS = $(libwebpdsp_la_LDFLAGS) @BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/dsp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/dsp/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebpdsp.la: $(libwebpdsp_la_OBJECTS) $(libwebpdsp_la_DEPENDENCIES) $(EXTRA_libwebpdsp_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebpdsp_la_LINK) $(libwebpdsp_la_OBJECTS) $(libwebpdsp_la_LIBADD) $(LIBS) libwebpdspdecode.la: $(libwebpdspdecode_la_OBJECTS) $(libwebpdspdecode_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebpdspdecode_la_LINK) $(am_libwebpdspdecode_la_rpath) $(libwebpdspdecode_la_OBJECTS) $(libwebpdspdecode_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-cpu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-dec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-dec_neon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-dec_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-enc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-enc_neon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-enc_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-lossless.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-upsampling.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-upsampling_neon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-upsampling_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-yuv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-cpu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-dec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-dec_neon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-dec_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-lossless.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-upsampling.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-upsampling_neon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-upsampling_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-yuv.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 $@ $< libwebpdsp_la-cpu.lo: cpu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-cpu.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-cpu.Tpo -c -o libwebpdsp_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-cpu.Tpo $(DEPDIR)/libwebpdsp_la-cpu.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpu.c' object='libwebpdsp_la-cpu.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c libwebpdsp_la-dec.lo: dec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-dec.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-dec.Tpo -c -o libwebpdsp_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-dec.Tpo $(DEPDIR)/libwebpdsp_la-dec.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec.c' object='libwebpdsp_la-dec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c libwebpdsp_la-dec_neon.lo: dec_neon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-dec_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-dec_neon.Tpo -c -o libwebpdsp_la-dec_neon.lo `test -f 'dec_neon.c' || echo '$(srcdir)/'`dec_neon.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-dec_neon.Tpo $(DEPDIR)/libwebpdsp_la-dec_neon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_neon.c' object='libwebpdsp_la-dec_neon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-dec_neon.lo `test -f 'dec_neon.c' || echo '$(srcdir)/'`dec_neon.c libwebpdsp_la-dec_sse2.lo: dec_sse2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-dec_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-dec_sse2.Tpo -c -o libwebpdsp_la-dec_sse2.lo `test -f 'dec_sse2.c' || echo '$(srcdir)/'`dec_sse2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-dec_sse2.Tpo $(DEPDIR)/libwebpdsp_la-dec_sse2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_sse2.c' object='libwebpdsp_la-dec_sse2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-dec_sse2.lo `test -f 'dec_sse2.c' || echo '$(srcdir)/'`dec_sse2.c libwebpdsp_la-lossless.lo: lossless.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-lossless.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-lossless.Tpo -c -o libwebpdsp_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-lossless.Tpo $(DEPDIR)/libwebpdsp_la-lossless.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless.c' object='libwebpdsp_la-lossless.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c libwebpdsp_la-upsampling.lo: upsampling.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-upsampling.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-upsampling.Tpo -c -o libwebpdsp_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-upsampling.Tpo $(DEPDIR)/libwebpdsp_la-upsampling.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling.c' object='libwebpdsp_la-upsampling.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c libwebpdsp_la-upsampling_neon.lo: upsampling_neon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-upsampling_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-upsampling_neon.Tpo -c -o libwebpdsp_la-upsampling_neon.lo `test -f 'upsampling_neon.c' || echo '$(srcdir)/'`upsampling_neon.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-upsampling_neon.Tpo $(DEPDIR)/libwebpdsp_la-upsampling_neon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_neon.c' object='libwebpdsp_la-upsampling_neon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-upsampling_neon.lo `test -f 'upsampling_neon.c' || echo '$(srcdir)/'`upsampling_neon.c libwebpdsp_la-upsampling_sse2.lo: upsampling_sse2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-upsampling_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-upsampling_sse2.Tpo -c -o libwebpdsp_la-upsampling_sse2.lo `test -f 'upsampling_sse2.c' || echo '$(srcdir)/'`upsampling_sse2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-upsampling_sse2.Tpo $(DEPDIR)/libwebpdsp_la-upsampling_sse2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_sse2.c' object='libwebpdsp_la-upsampling_sse2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-upsampling_sse2.lo `test -f 'upsampling_sse2.c' || echo '$(srcdir)/'`upsampling_sse2.c libwebpdsp_la-yuv.lo: yuv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-yuv.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-yuv.Tpo -c -o libwebpdsp_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-yuv.Tpo $(DEPDIR)/libwebpdsp_la-yuv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv.c' object='libwebpdsp_la-yuv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c libwebpdsp_la-enc.lo: enc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-enc.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-enc.Tpo -c -o libwebpdsp_la-enc.lo `test -f 'enc.c' || echo '$(srcdir)/'`enc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-enc.Tpo $(DEPDIR)/libwebpdsp_la-enc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc.c' object='libwebpdsp_la-enc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-enc.lo `test -f 'enc.c' || echo '$(srcdir)/'`enc.c libwebpdsp_la-enc_neon.lo: enc_neon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-enc_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-enc_neon.Tpo -c -o libwebpdsp_la-enc_neon.lo `test -f 'enc_neon.c' || echo '$(srcdir)/'`enc_neon.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-enc_neon.Tpo $(DEPDIR)/libwebpdsp_la-enc_neon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_neon.c' object='libwebpdsp_la-enc_neon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-enc_neon.lo `test -f 'enc_neon.c' || echo '$(srcdir)/'`enc_neon.c libwebpdsp_la-enc_sse2.lo: enc_sse2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-enc_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-enc_sse2.Tpo -c -o libwebpdsp_la-enc_sse2.lo `test -f 'enc_sse2.c' || echo '$(srcdir)/'`enc_sse2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-enc_sse2.Tpo $(DEPDIR)/libwebpdsp_la-enc_sse2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_sse2.c' object='libwebpdsp_la-enc_sse2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-enc_sse2.lo `test -f 'enc_sse2.c' || echo '$(srcdir)/'`enc_sse2.c libwebpdspdecode_la-cpu.lo: cpu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-cpu.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-cpu.Tpo -c -o libwebpdspdecode_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-cpu.Tpo $(DEPDIR)/libwebpdspdecode_la-cpu.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpu.c' object='libwebpdspdecode_la-cpu.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c libwebpdspdecode_la-dec.lo: dec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-dec.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-dec.Tpo -c -o libwebpdspdecode_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-dec.Tpo $(DEPDIR)/libwebpdspdecode_la-dec.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec.c' object='libwebpdspdecode_la-dec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c libwebpdspdecode_la-dec_neon.lo: dec_neon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-dec_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-dec_neon.Tpo -c -o libwebpdspdecode_la-dec_neon.lo `test -f 'dec_neon.c' || echo '$(srcdir)/'`dec_neon.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-dec_neon.Tpo $(DEPDIR)/libwebpdspdecode_la-dec_neon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_neon.c' object='libwebpdspdecode_la-dec_neon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-dec_neon.lo `test -f 'dec_neon.c' || echo '$(srcdir)/'`dec_neon.c libwebpdspdecode_la-dec_sse2.lo: dec_sse2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-dec_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-dec_sse2.Tpo -c -o libwebpdspdecode_la-dec_sse2.lo `test -f 'dec_sse2.c' || echo '$(srcdir)/'`dec_sse2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-dec_sse2.Tpo $(DEPDIR)/libwebpdspdecode_la-dec_sse2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_sse2.c' object='libwebpdspdecode_la-dec_sse2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-dec_sse2.lo `test -f 'dec_sse2.c' || echo '$(srcdir)/'`dec_sse2.c libwebpdspdecode_la-lossless.lo: lossless.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-lossless.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-lossless.Tpo -c -o libwebpdspdecode_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-lossless.Tpo $(DEPDIR)/libwebpdspdecode_la-lossless.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless.c' object='libwebpdspdecode_la-lossless.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c libwebpdspdecode_la-upsampling.lo: upsampling.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-upsampling.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-upsampling.Tpo -c -o libwebpdspdecode_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-upsampling.Tpo $(DEPDIR)/libwebpdspdecode_la-upsampling.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling.c' object='libwebpdspdecode_la-upsampling.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c libwebpdspdecode_la-upsampling_neon.lo: upsampling_neon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-upsampling_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-upsampling_neon.Tpo -c -o libwebpdspdecode_la-upsampling_neon.lo `test -f 'upsampling_neon.c' || echo '$(srcdir)/'`upsampling_neon.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-upsampling_neon.Tpo $(DEPDIR)/libwebpdspdecode_la-upsampling_neon.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_neon.c' object='libwebpdspdecode_la-upsampling_neon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-upsampling_neon.lo `test -f 'upsampling_neon.c' || echo '$(srcdir)/'`upsampling_neon.c libwebpdspdecode_la-upsampling_sse2.lo: upsampling_sse2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-upsampling_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-upsampling_sse2.Tpo -c -o libwebpdspdecode_la-upsampling_sse2.lo `test -f 'upsampling_sse2.c' || echo '$(srcdir)/'`upsampling_sse2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-upsampling_sse2.Tpo $(DEPDIR)/libwebpdspdecode_la-upsampling_sse2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_sse2.c' object='libwebpdspdecode_la-upsampling_sse2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-upsampling_sse2.lo `test -f 'upsampling_sse2.c' || echo '$(srcdir)/'`upsampling_sse2.c libwebpdspdecode_la-yuv.lo: yuv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-yuv.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-yuv.Tpo -c -o libwebpdspdecode_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-yuv.Tpo $(DEPDIR)/libwebpdspdecode_la-yuv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv.c' object='libwebpdspdecode_la-yuv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-commonHEADERS: $(common_HEADERS) @$(NORMAL_INSTALL) test -z "$(commondir)" || $(MKDIR_P) "$(DESTDIR)$(commondir)" @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(commondir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(commondir)" || exit $$?; \ done uninstall-commonHEADERS: @$(NORMAL_UNINSTALL) @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(commondir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(commondir)"; 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-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-commonHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: 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 -rf ./$(DEPDIR) -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-commonHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-commonHEADERS 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-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 uninstall uninstall-am uninstall-commonHEADERS # 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: libwebp-0.4.0/src/dsp/dec_sse2.c0000644000014400001440000011232012255002107013250 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // SSE2 version of some decoding functions (idct, loop filtering). // // Author: somnath@google.com (Somnath Banerjee) // cduvivier@google.com (Christian Duvivier) #include "./dsp.h" #if defined(WEBP_USE_SSE2) // The 3-coeff sparse transform in SSE2 is not really faster than the plain-C // one it seems => disable it by default. Uncomment the following to enable: // #define USE_TRANSFORM_AC3 #include #include "../dec/vp8i.h" //------------------------------------------------------------------------------ // Transforms (Paragraph 14.4) static void TransformSSE2(const int16_t* in, uint8_t* dst, int do_two) { // This implementation makes use of 16-bit fixed point versions of two // multiply constants: // K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16 // K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16 // // To be able to use signed 16-bit integers, we use the following trick to // have constants within range: // - Associated constants are obtained by subtracting the 16-bit fixed point // version of one: // k = K - (1 << 16) => K = k + (1 << 16) // K1 = 85267 => k1 = 20091 // K2 = 35468 => k2 = -30068 // - The multiplication of a variable by a constant become the sum of the // variable and the multiplication of that variable by the associated // constant: // (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x const __m128i k1 = _mm_set1_epi16(20091); const __m128i k2 = _mm_set1_epi16(-30068); __m128i T0, T1, T2, T3; // Load and concatenate the transform coefficients (we'll do two transforms // in parallel). In the case of only one transform, the second half of the // vectors will just contain random value we'll never use nor store. __m128i in0, in1, in2, in3; { in0 = _mm_loadl_epi64((__m128i*)&in[0]); in1 = _mm_loadl_epi64((__m128i*)&in[4]); in2 = _mm_loadl_epi64((__m128i*)&in[8]); in3 = _mm_loadl_epi64((__m128i*)&in[12]); // a00 a10 a20 a30 x x x x // a01 a11 a21 a31 x x x x // a02 a12 a22 a32 x x x x // a03 a13 a23 a33 x x x x if (do_two) { const __m128i inB0 = _mm_loadl_epi64((__m128i*)&in[16]); const __m128i inB1 = _mm_loadl_epi64((__m128i*)&in[20]); const __m128i inB2 = _mm_loadl_epi64((__m128i*)&in[24]); const __m128i inB3 = _mm_loadl_epi64((__m128i*)&in[28]); in0 = _mm_unpacklo_epi64(in0, inB0); in1 = _mm_unpacklo_epi64(in1, inB1); in2 = _mm_unpacklo_epi64(in2, inB2); in3 = _mm_unpacklo_epi64(in3, inB3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } } // Vertical pass and subsequent transpose. { // First pass, c and d calculations are longer because of the "trick" // multiplications. const __m128i a = _mm_add_epi16(in0, in2); const __m128i b = _mm_sub_epi16(in0, in2); // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3 const __m128i c1 = _mm_mulhi_epi16(in1, k2); const __m128i c2 = _mm_mulhi_epi16(in3, k1); const __m128i c3 = _mm_sub_epi16(in1, in3); const __m128i c4 = _mm_sub_epi16(c1, c2); const __m128i c = _mm_add_epi16(c3, c4); // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3 const __m128i d1 = _mm_mulhi_epi16(in1, k1); const __m128i d2 = _mm_mulhi_epi16(in3, k2); const __m128i d3 = _mm_add_epi16(in1, in3); const __m128i d4 = _mm_add_epi16(d1, d2); const __m128i d = _mm_add_epi16(d3, d4); // Second pass. const __m128i tmp0 = _mm_add_epi16(a, d); const __m128i tmp1 = _mm_add_epi16(b, c); const __m128i tmp2 = _mm_sub_epi16(b, c); const __m128i tmp3 = _mm_sub_epi16(a, d); // Transpose the two 4x4. // a00 a01 a02 a03 b00 b01 b02 b03 // a10 a11 a12 a13 b10 b11 b12 b13 // a20 a21 a22 a23 b20 b21 b22 b23 // a30 a31 a32 a33 b30 b31 b32 b33 const __m128i transpose0_0 = _mm_unpacklo_epi16(tmp0, tmp1); const __m128i transpose0_1 = _mm_unpacklo_epi16(tmp2, tmp3); const __m128i transpose0_2 = _mm_unpackhi_epi16(tmp0, tmp1); const __m128i transpose0_3 = _mm_unpackhi_epi16(tmp2, tmp3); // a00 a10 a01 a11 a02 a12 a03 a13 // a20 a30 a21 a31 a22 a32 a23 a33 // b00 b10 b01 b11 b02 b12 b03 b13 // b20 b30 b21 b31 b22 b32 b23 b33 const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1); const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3); const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1); const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3); // a00 a10 a20 a30 a01 a11 a21 a31 // b00 b10 b20 b30 b01 b11 b21 b31 // a02 a12 a22 a32 a03 a13 a23 a33 // b02 b12 a22 b32 b03 b13 b23 b33 T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } // Horizontal pass and subsequent transpose. { // First pass, c and d calculations are longer because of the "trick" // multiplications. const __m128i four = _mm_set1_epi16(4); const __m128i dc = _mm_add_epi16(T0, four); const __m128i a = _mm_add_epi16(dc, T2); const __m128i b = _mm_sub_epi16(dc, T2); // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3 const __m128i c1 = _mm_mulhi_epi16(T1, k2); const __m128i c2 = _mm_mulhi_epi16(T3, k1); const __m128i c3 = _mm_sub_epi16(T1, T3); const __m128i c4 = _mm_sub_epi16(c1, c2); const __m128i c = _mm_add_epi16(c3, c4); // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3 const __m128i d1 = _mm_mulhi_epi16(T1, k1); const __m128i d2 = _mm_mulhi_epi16(T3, k2); const __m128i d3 = _mm_add_epi16(T1, T3); const __m128i d4 = _mm_add_epi16(d1, d2); const __m128i d = _mm_add_epi16(d3, d4); // Second pass. const __m128i tmp0 = _mm_add_epi16(a, d); const __m128i tmp1 = _mm_add_epi16(b, c); const __m128i tmp2 = _mm_sub_epi16(b, c); const __m128i tmp3 = _mm_sub_epi16(a, d); const __m128i shifted0 = _mm_srai_epi16(tmp0, 3); const __m128i shifted1 = _mm_srai_epi16(tmp1, 3); const __m128i shifted2 = _mm_srai_epi16(tmp2, 3); const __m128i shifted3 = _mm_srai_epi16(tmp3, 3); // Transpose the two 4x4. // a00 a01 a02 a03 b00 b01 b02 b03 // a10 a11 a12 a13 b10 b11 b12 b13 // a20 a21 a22 a23 b20 b21 b22 b23 // a30 a31 a32 a33 b30 b31 b32 b33 const __m128i transpose0_0 = _mm_unpacklo_epi16(shifted0, shifted1); const __m128i transpose0_1 = _mm_unpacklo_epi16(shifted2, shifted3); const __m128i transpose0_2 = _mm_unpackhi_epi16(shifted0, shifted1); const __m128i transpose0_3 = _mm_unpackhi_epi16(shifted2, shifted3); // a00 a10 a01 a11 a02 a12 a03 a13 // a20 a30 a21 a31 a22 a32 a23 a33 // b00 b10 b01 b11 b02 b12 b03 b13 // b20 b30 b21 b31 b22 b32 b23 b33 const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1); const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3); const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1); const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3); // a00 a10 a20 a30 a01 a11 a21 a31 // b00 b10 b20 b30 b01 b11 b21 b31 // a02 a12 a22 a32 a03 a13 a23 a33 // b02 b12 a22 b32 b03 b13 b23 b33 T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); // a00 a10 a20 a30 b00 b10 b20 b30 // a01 a11 a21 a31 b01 b11 b21 b31 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } // Add inverse transform to 'dst' and store. { const __m128i zero = _mm_setzero_si128(); // Load the reference(s). __m128i dst0, dst1, dst2, dst3; if (do_two) { // Load eight bytes/pixels per line. dst0 = _mm_loadl_epi64((__m128i*)(dst + 0 * BPS)); dst1 = _mm_loadl_epi64((__m128i*)(dst + 1 * BPS)); dst2 = _mm_loadl_epi64((__m128i*)(dst + 2 * BPS)); dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS)); } else { // Load four bytes/pixels per line. dst0 = _mm_cvtsi32_si128(*(int*)(dst + 0 * BPS)); dst1 = _mm_cvtsi32_si128(*(int*)(dst + 1 * BPS)); dst2 = _mm_cvtsi32_si128(*(int*)(dst + 2 * BPS)); dst3 = _mm_cvtsi32_si128(*(int*)(dst + 3 * BPS)); } // Convert to 16b. dst0 = _mm_unpacklo_epi8(dst0, zero); dst1 = _mm_unpacklo_epi8(dst1, zero); dst2 = _mm_unpacklo_epi8(dst2, zero); dst3 = _mm_unpacklo_epi8(dst3, zero); // Add the inverse transform(s). dst0 = _mm_add_epi16(dst0, T0); dst1 = _mm_add_epi16(dst1, T1); dst2 = _mm_add_epi16(dst2, T2); dst3 = _mm_add_epi16(dst3, T3); // Unsigned saturate to 8b. dst0 = _mm_packus_epi16(dst0, dst0); dst1 = _mm_packus_epi16(dst1, dst1); dst2 = _mm_packus_epi16(dst2, dst2); dst3 = _mm_packus_epi16(dst3, dst3); // Store the results. if (do_two) { // Store eight bytes/pixels per line. _mm_storel_epi64((__m128i*)(dst + 0 * BPS), dst0); _mm_storel_epi64((__m128i*)(dst + 1 * BPS), dst1); _mm_storel_epi64((__m128i*)(dst + 2 * BPS), dst2); _mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3); } else { // Store four bytes/pixels per line. *(int*)(dst + 0 * BPS) = _mm_cvtsi128_si32(dst0); *(int*)(dst + 1 * BPS) = _mm_cvtsi128_si32(dst1); *(int*)(dst + 2 * BPS) = _mm_cvtsi128_si32(dst2); *(int*)(dst + 3 * BPS) = _mm_cvtsi128_si32(dst3); } } } #if defined(USE_TRANSFORM_AC3) #define MUL(a, b) (((a) * (b)) >> 16) static void TransformAC3SSE2(const int16_t* in, uint8_t* dst) { static const int kC1 = 20091 + (1 << 16); static const int kC2 = 35468; const __m128i A = _mm_set1_epi16(in[0] + 4); const __m128i c4 = _mm_set1_epi16(MUL(in[4], kC2)); const __m128i d4 = _mm_set1_epi16(MUL(in[4], kC1)); const int c1 = MUL(in[1], kC2); const int d1 = MUL(in[1], kC1); const __m128i CD = _mm_set_epi16(0, 0, 0, 0, -d1, -c1, c1, d1); const __m128i B = _mm_adds_epi16(A, CD); const __m128i m0 = _mm_adds_epi16(B, d4); const __m128i m1 = _mm_adds_epi16(B, c4); const __m128i m2 = _mm_subs_epi16(B, c4); const __m128i m3 = _mm_subs_epi16(B, d4); const __m128i zero = _mm_setzero_si128(); // Load the source pixels. __m128i dst0 = _mm_cvtsi32_si128(*(int*)(dst + 0 * BPS)); __m128i dst1 = _mm_cvtsi32_si128(*(int*)(dst + 1 * BPS)); __m128i dst2 = _mm_cvtsi32_si128(*(int*)(dst + 2 * BPS)); __m128i dst3 = _mm_cvtsi32_si128(*(int*)(dst + 3 * BPS)); // Convert to 16b. dst0 = _mm_unpacklo_epi8(dst0, zero); dst1 = _mm_unpacklo_epi8(dst1, zero); dst2 = _mm_unpacklo_epi8(dst2, zero); dst3 = _mm_unpacklo_epi8(dst3, zero); // Add the inverse transform. dst0 = _mm_adds_epi16(dst0, _mm_srai_epi16(m0, 3)); dst1 = _mm_adds_epi16(dst1, _mm_srai_epi16(m1, 3)); dst2 = _mm_adds_epi16(dst2, _mm_srai_epi16(m2, 3)); dst3 = _mm_adds_epi16(dst3, _mm_srai_epi16(m3, 3)); // Unsigned saturate to 8b. dst0 = _mm_packus_epi16(dst0, dst0); dst1 = _mm_packus_epi16(dst1, dst1); dst2 = _mm_packus_epi16(dst2, dst2); dst3 = _mm_packus_epi16(dst3, dst3); // Store the results. *(int*)(dst + 0 * BPS) = _mm_cvtsi128_si32(dst0); *(int*)(dst + 1 * BPS) = _mm_cvtsi128_si32(dst1); *(int*)(dst + 2 * BPS) = _mm_cvtsi128_si32(dst2); *(int*)(dst + 3 * BPS) = _mm_cvtsi128_si32(dst3); } #undef MUL #endif // USE_TRANSFORM_AC3 //------------------------------------------------------------------------------ // Loop Filter (Paragraph 15) // Compute abs(p - q) = subs(p - q) OR subs(q - p) #define MM_ABS(p, q) _mm_or_si128( \ _mm_subs_epu8((q), (p)), \ _mm_subs_epu8((p), (q))) // Shift each byte of "a" by N bits while preserving by the sign bit. // // It first shifts the lower bytes of the words and then the upper bytes and // then merges the results together. #define SIGNED_SHIFT_N(a, N) { \ __m128i t = a; \ t = _mm_slli_epi16(t, 8); \ t = _mm_srai_epi16(t, N); \ t = _mm_srli_epi16(t, 8); \ \ a = _mm_srai_epi16(a, N + 8); \ a = _mm_slli_epi16(a, 8); \ \ a = _mm_or_si128(t, a); \ } #define FLIP_SIGN_BIT2(a, b) { \ a = _mm_xor_si128(a, sign_bit); \ b = _mm_xor_si128(b, sign_bit); \ } #define FLIP_SIGN_BIT4(a, b, c, d) { \ FLIP_SIGN_BIT2(a, b); \ FLIP_SIGN_BIT2(c, d); \ } #define GET_NOTHEV(p1, p0, q0, q1, hev_thresh, not_hev) { \ const __m128i zero = _mm_setzero_si128(); \ const __m128i t_1 = MM_ABS(p1, p0); \ const __m128i t_2 = MM_ABS(q1, q0); \ \ const __m128i h = _mm_set1_epi8(hev_thresh); \ const __m128i t_3 = _mm_subs_epu8(t_1, h); /* abs(p1 - p0) - hev_tresh */ \ const __m128i t_4 = _mm_subs_epu8(t_2, h); /* abs(q1 - q0) - hev_tresh */ \ \ not_hev = _mm_or_si128(t_3, t_4); \ not_hev = _mm_cmpeq_epi8(not_hev, zero); /* not_hev <= t1 && not_hev <= t2 */\ } #define GET_BASE_DELTA(p1, p0, q0, q1, o) { \ const __m128i qp0 = _mm_subs_epi8(q0, p0); /* q0 - p0 */ \ o = _mm_subs_epi8(p1, q1); /* p1 - q1 */ \ o = _mm_adds_epi8(o, qp0); /* p1 - q1 + 1 * (q0 - p0) */ \ o = _mm_adds_epi8(o, qp0); /* p1 - q1 + 2 * (q0 - p0) */ \ o = _mm_adds_epi8(o, qp0); /* p1 - q1 + 3 * (q0 - p0) */ \ } #define DO_SIMPLE_FILTER(p0, q0, fl) { \ const __m128i three = _mm_set1_epi8(3); \ const __m128i four = _mm_set1_epi8(4); \ __m128i v3 = _mm_adds_epi8(fl, three); \ __m128i v4 = _mm_adds_epi8(fl, four); \ \ /* Do +4 side */ \ SIGNED_SHIFT_N(v4, 3); /* v4 >> 3 */ \ q0 = _mm_subs_epi8(q0, v4); /* q0 -= v4 */ \ \ /* Now do +3 side */ \ SIGNED_SHIFT_N(v3, 3); /* v3 >> 3 */ \ p0 = _mm_adds_epi8(p0, v3); /* p0 += v3 */ \ } // Updates values of 2 pixels at MB edge during complex filtering. // Update operations: // q = q - delta and p = p + delta; where delta = [(a_hi >> 7), (a_lo >> 7)] #define UPDATE_2PIXELS(pi, qi, a_lo, a_hi) { \ const __m128i a_lo7 = _mm_srai_epi16(a_lo, 7); \ const __m128i a_hi7 = _mm_srai_epi16(a_hi, 7); \ const __m128i delta = _mm_packs_epi16(a_lo7, a_hi7); \ pi = _mm_adds_epi8(pi, delta); \ qi = _mm_subs_epi8(qi, delta); \ } static void NeedsFilter(const __m128i* p1, const __m128i* p0, const __m128i* q0, const __m128i* q1, int thresh, __m128i *mask) { __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1) *mask = _mm_set1_epi8(0xFE); t1 = _mm_and_si128(t1, *mask); // set lsb of each byte to zero t1 = _mm_srli_epi16(t1, 1); // abs(p1 - q1) / 2 *mask = MM_ABS(*p0, *q0); // abs(p0 - q0) *mask = _mm_adds_epu8(*mask, *mask); // abs(p0 - q0) * 2 *mask = _mm_adds_epu8(*mask, t1); // abs(p0 - q0) * 2 + abs(p1 - q1) / 2 t1 = _mm_set1_epi8(thresh); *mask = _mm_subs_epu8(*mask, t1); // mask <= thresh *mask = _mm_cmpeq_epi8(*mask, _mm_setzero_si128()); } //------------------------------------------------------------------------------ // Edge filtering functions // Applies filter on 2 pixels (p0 and q0) static WEBP_INLINE void DoFilter2(const __m128i* p1, __m128i* p0, __m128i* q0, const __m128i* q1, int thresh) { __m128i a, mask; const __m128i sign_bit = _mm_set1_epi8(0x80); const __m128i p1s = _mm_xor_si128(*p1, sign_bit); const __m128i q1s = _mm_xor_si128(*q1, sign_bit); NeedsFilter(p1, p0, q0, q1, thresh, &mask); // convert to signed values FLIP_SIGN_BIT2(*p0, *q0); GET_BASE_DELTA(p1s, *p0, *q0, q1s, a); a = _mm_and_si128(a, mask); // mask filter values we don't care about DO_SIMPLE_FILTER(*p0, *q0, a); // unoffset FLIP_SIGN_BIT2(*p0, *q0); } // Applies filter on 4 pixels (p1, p0, q0 and q1) static WEBP_INLINE void DoFilter4(__m128i* p1, __m128i *p0, __m128i* q0, __m128i* q1, const __m128i* mask, int hev_thresh) { __m128i not_hev; __m128i t1, t2, t3; const __m128i sign_bit = _mm_set1_epi8(0x80); // compute hev mask GET_NOTHEV(*p1, *p0, *q0, *q1, hev_thresh, not_hev); // convert to signed values FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1); t1 = _mm_subs_epi8(*p1, *q1); // p1 - q1 t1 = _mm_andnot_si128(not_hev, t1); // hev(p1 - q1) t2 = _mm_subs_epi8(*q0, *p0); // q0 - p0 t1 = _mm_adds_epi8(t1, t2); // hev(p1 - q1) + 1 * (q0 - p0) t1 = _mm_adds_epi8(t1, t2); // hev(p1 - q1) + 2 * (q0 - p0) t1 = _mm_adds_epi8(t1, t2); // hev(p1 - q1) + 3 * (q0 - p0) t1 = _mm_and_si128(t1, *mask); // mask filter values we don't care about // Do +4 side t2 = _mm_set1_epi8(4); t2 = _mm_adds_epi8(t1, t2); // 3 * (q0 - p0) + (p1 - q1) + 4 SIGNED_SHIFT_N(t2, 3); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3 t3 = t2; // save t2 *q0 = _mm_subs_epi8(*q0, t2); // q0 -= t2 // Now do +3 side t2 = _mm_set1_epi8(3); t2 = _mm_adds_epi8(t1, t2); // +3 instead of +4 SIGNED_SHIFT_N(t2, 3); // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3 *p0 = _mm_adds_epi8(*p0, t2); // p0 += t2 t2 = _mm_set1_epi8(1); t3 = _mm_adds_epi8(t3, t2); SIGNED_SHIFT_N(t3, 1); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 4 t3 = _mm_and_si128(not_hev, t3); // if !hev *q1 = _mm_subs_epi8(*q1, t3); // q1 -= t3 *p1 = _mm_adds_epi8(*p1, t3); // p1 += t3 // unoffset FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1); } // Applies filter on 6 pixels (p2, p1, p0, q0, q1 and q2) static WEBP_INLINE void DoFilter6(__m128i *p2, __m128i* p1, __m128i *p0, __m128i* q0, __m128i* q1, __m128i *q2, const __m128i* mask, int hev_thresh) { __m128i a, not_hev; const __m128i sign_bit = _mm_set1_epi8(0x80); // compute hev mask GET_NOTHEV(*p1, *p0, *q0, *q1, hev_thresh, not_hev); // convert to signed values FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1); FLIP_SIGN_BIT2(*p2, *q2); GET_BASE_DELTA(*p1, *p0, *q0, *q1, a); { // do simple filter on pixels with hev const __m128i m = _mm_andnot_si128(not_hev, *mask); const __m128i f = _mm_and_si128(a, m); DO_SIMPLE_FILTER(*p0, *q0, f); } { // do strong filter on pixels with not hev const __m128i zero = _mm_setzero_si128(); const __m128i nine = _mm_set1_epi16(0x0900); const __m128i sixty_three = _mm_set1_epi16(63); const __m128i m = _mm_and_si128(not_hev, *mask); const __m128i f = _mm_and_si128(a, m); const __m128i f_lo = _mm_unpacklo_epi8(zero, f); const __m128i f_hi = _mm_unpackhi_epi8(zero, f); const __m128i f9_lo = _mm_mulhi_epi16(f_lo, nine); // Filter (lo) * 9 const __m128i f9_hi = _mm_mulhi_epi16(f_hi, nine); // Filter (hi) * 9 const __m128i f18_lo = _mm_add_epi16(f9_lo, f9_lo); // Filter (lo) * 18 const __m128i f18_hi = _mm_add_epi16(f9_hi, f9_hi); // Filter (hi) * 18 const __m128i a2_lo = _mm_add_epi16(f9_lo, sixty_three); // Filter * 9 + 63 const __m128i a2_hi = _mm_add_epi16(f9_hi, sixty_three); // Filter * 9 + 63 const __m128i a1_lo = _mm_add_epi16(f18_lo, sixty_three); // F... * 18 + 63 const __m128i a1_hi = _mm_add_epi16(f18_hi, sixty_three); // F... * 18 + 63 const __m128i a0_lo = _mm_add_epi16(f18_lo, a2_lo); // Filter * 27 + 63 const __m128i a0_hi = _mm_add_epi16(f18_hi, a2_hi); // Filter * 27 + 63 UPDATE_2PIXELS(*p2, *q2, a2_lo, a2_hi); UPDATE_2PIXELS(*p1, *q1, a1_lo, a1_hi); UPDATE_2PIXELS(*p0, *q0, a0_lo, a0_hi); } // unoffset FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1); FLIP_SIGN_BIT2(*p2, *q2); } // reads 8 rows across a vertical edge. // // TODO(somnath): Investigate _mm_shuffle* also see if it can be broken into // two Load4x4() to avoid code duplication. static WEBP_INLINE void Load8x4(const uint8_t* b, int stride, __m128i* p, __m128i* q) { __m128i t1, t2; // Load 0th, 1st, 4th and 5th rows __m128i r0 = _mm_cvtsi32_si128(*((int*)&b[0 * stride])); // 03 02 01 00 __m128i r1 = _mm_cvtsi32_si128(*((int*)&b[1 * stride])); // 13 12 11 10 __m128i r4 = _mm_cvtsi32_si128(*((int*)&b[4 * stride])); // 43 42 41 40 __m128i r5 = _mm_cvtsi32_si128(*((int*)&b[5 * stride])); // 53 52 51 50 r0 = _mm_unpacklo_epi32(r0, r4); // 43 42 41 40 03 02 01 00 r1 = _mm_unpacklo_epi32(r1, r5); // 53 52 51 50 13 12 11 10 // t1 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00 t1 = _mm_unpacklo_epi8(r0, r1); // Load 2nd, 3rd, 6th and 7th rows r0 = _mm_cvtsi32_si128(*((int*)&b[2 * stride])); // 23 22 21 22 r1 = _mm_cvtsi32_si128(*((int*)&b[3 * stride])); // 33 32 31 30 r4 = _mm_cvtsi32_si128(*((int*)&b[6 * stride])); // 63 62 61 60 r5 = _mm_cvtsi32_si128(*((int*)&b[7 * stride])); // 73 72 71 70 r0 = _mm_unpacklo_epi32(r0, r4); // 63 62 61 60 23 22 21 20 r1 = _mm_unpacklo_epi32(r1, r5); // 73 72 71 70 33 32 31 30 // t2 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20 t2 = _mm_unpacklo_epi8(r0, r1); // t1 = 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00 // t2 = 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40 r0 = t1; t1 = _mm_unpacklo_epi16(t1, t2); t2 = _mm_unpackhi_epi16(r0, t2); // *p = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00 // *q = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02 *p = _mm_unpacklo_epi32(t1, t2); *q = _mm_unpackhi_epi32(t1, t2); } static WEBP_INLINE void Load16x4(const uint8_t* r0, const uint8_t* r8, int stride, __m128i* p1, __m128i* p0, __m128i* q0, __m128i* q1) { __m128i t1, t2; // Assume the pixels around the edge (|) are numbered as follows // 00 01 | 02 03 // 10 11 | 12 13 // ... | ... // e0 e1 | e2 e3 // f0 f1 | f2 f3 // // r0 is pointing to the 0th row (00) // r8 is pointing to the 8th row (80) // Load // p1 = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00 // q0 = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02 // p0 = f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80 // q1 = f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82 Load8x4(r0, stride, p1, q0); Load8x4(r8, stride, p0, q1); t1 = *p1; t2 = *q0; // p1 = f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00 // p0 = f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01 // q0 = f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 // q1 = f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03 *p1 = _mm_unpacklo_epi64(t1, *p0); *p0 = _mm_unpackhi_epi64(t1, *p0); *q0 = _mm_unpacklo_epi64(t2, *q1); *q1 = _mm_unpackhi_epi64(t2, *q1); } static WEBP_INLINE void Store4x4(__m128i* x, uint8_t* dst, int stride) { int i; for (i = 0; i < 4; ++i, dst += stride) { *((int32_t*)dst) = _mm_cvtsi128_si32(*x); *x = _mm_srli_si128(*x, 4); } } // Transpose back and store static WEBP_INLINE void Store16x4(uint8_t* r0, uint8_t* r8, int stride, __m128i* p1, __m128i* p0, __m128i* q0, __m128i* q1) { __m128i t1; // p0 = 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00 // p1 = f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80 t1 = *p0; *p0 = _mm_unpacklo_epi8(*p1, t1); *p1 = _mm_unpackhi_epi8(*p1, t1); // q0 = 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02 // q1 = f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82 t1 = *q0; *q0 = _mm_unpacklo_epi8(t1, *q1); *q1 = _mm_unpackhi_epi8(t1, *q1); // p0 = 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00 // q0 = 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40 t1 = *p0; *p0 = _mm_unpacklo_epi16(t1, *q0); *q0 = _mm_unpackhi_epi16(t1, *q0); // p1 = b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80 // q1 = f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0 t1 = *p1; *p1 = _mm_unpacklo_epi16(t1, *q1); *q1 = _mm_unpackhi_epi16(t1, *q1); Store4x4(p0, r0, stride); r0 += 4 * stride; Store4x4(q0, r0, stride); Store4x4(p1, r8, stride); r8 += 4 * stride; Store4x4(q1, r8, stride); } //------------------------------------------------------------------------------ // Simple In-loop filtering (Paragraph 15.2) static void SimpleVFilter16SSE2(uint8_t* p, int stride, int thresh) { // Load __m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]); __m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]); __m128i q0 = _mm_loadu_si128((__m128i*)&p[0]); __m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]); DoFilter2(&p1, &p0, &q0, &q1, thresh); // Store _mm_storeu_si128((__m128i*)&p[-stride], p0); _mm_storeu_si128((__m128i*)p, q0); } static void SimpleHFilter16SSE2(uint8_t* p, int stride, int thresh) { __m128i p1, p0, q0, q1; p -= 2; // beginning of p1 Load16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1); DoFilter2(&p1, &p0, &q0, &q1, thresh); Store16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1); } static void SimpleVFilter16iSSE2(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4 * stride; SimpleVFilter16SSE2(p, stride, thresh); } } static void SimpleHFilter16iSSE2(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4; SimpleHFilter16SSE2(p, stride, thresh); } } //------------------------------------------------------------------------------ // Complex In-loop filtering (Paragraph 15.3) #define MAX_DIFF1(p3, p2, p1, p0, m) { \ m = MM_ABS(p3, p2); \ m = _mm_max_epu8(m, MM_ABS(p2, p1)); \ m = _mm_max_epu8(m, MM_ABS(p1, p0)); \ } #define MAX_DIFF2(p3, p2, p1, p0, m) { \ m = _mm_max_epu8(m, MM_ABS(p3, p2)); \ m = _mm_max_epu8(m, MM_ABS(p2, p1)); \ m = _mm_max_epu8(m, MM_ABS(p1, p0)); \ } #define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) { \ e1 = _mm_loadu_si128((__m128i*)&(p)[0 * stride]); \ e2 = _mm_loadu_si128((__m128i*)&(p)[1 * stride]); \ e3 = _mm_loadu_si128((__m128i*)&(p)[2 * stride]); \ e4 = _mm_loadu_si128((__m128i*)&(p)[3 * stride]); \ } #define LOADUV_H_EDGE(p, u, v, stride) { \ p = _mm_loadl_epi64((__m128i*)&(u)[(stride)]); \ p = _mm_unpacklo_epi64(p, _mm_loadl_epi64((__m128i*)&(v)[(stride)])); \ } #define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) { \ LOADUV_H_EDGE(e1, u, v, 0 * stride); \ LOADUV_H_EDGE(e2, u, v, 1 * stride); \ LOADUV_H_EDGE(e3, u, v, 2 * stride); \ LOADUV_H_EDGE(e4, u, v, 3 * stride); \ } #define STOREUV(p, u, v, stride) { \ _mm_storel_epi64((__m128i*)&u[(stride)], p); \ p = _mm_srli_si128(p, 8); \ _mm_storel_epi64((__m128i*)&v[(stride)], p); \ } #define COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask) { \ __m128i fl_yes; \ const __m128i it = _mm_set1_epi8(ithresh); \ mask = _mm_subs_epu8(mask, it); \ mask = _mm_cmpeq_epi8(mask, _mm_setzero_si128()); \ NeedsFilter(&p1, &p0, &q0, &q1, thresh, &fl_yes); \ mask = _mm_and_si128(mask, fl_yes); \ } // on macroblock edges static void VFilter16SSE2(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { __m128i t1; __m128i mask; __m128i p2, p1, p0, q0, q1, q2; // Load p3, p2, p1, p0 LOAD_H_EDGES4(p - 4 * stride, stride, t1, p2, p1, p0); MAX_DIFF1(t1, p2, p1, p0, mask); // Load q0, q1, q2, q3 LOAD_H_EDGES4(p, stride, q0, q1, q2, t1); MAX_DIFF2(t1, q2, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh); // Store _mm_storeu_si128((__m128i*)&p[-3 * stride], p2); _mm_storeu_si128((__m128i*)&p[-2 * stride], p1); _mm_storeu_si128((__m128i*)&p[-1 * stride], p0); _mm_storeu_si128((__m128i*)&p[0 * stride], q0); _mm_storeu_si128((__m128i*)&p[1 * stride], q1); _mm_storeu_si128((__m128i*)&p[2 * stride], q2); } static void HFilter16SSE2(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { __m128i mask; __m128i p3, p2, p1, p0, q0, q1, q2, q3; uint8_t* const b = p - 4; Load16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0); // p3, p2, p1, p0 MAX_DIFF1(p3, p2, p1, p0, mask); Load16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3); // q0, q1, q2, q3 MAX_DIFF2(q3, q2, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh); Store16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0); Store16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3); } // on three inner edges static void VFilter16iSSE2(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { int k; __m128i mask; __m128i t1, t2, p1, p0, q0, q1; for (k = 3; k > 0; --k) { // Load p3, p2, p1, p0 LOAD_H_EDGES4(p, stride, t2, t1, p1, p0); MAX_DIFF1(t2, t1, p1, p0, mask); p += 4 * stride; // Load q0, q1, q2, q3 LOAD_H_EDGES4(p, stride, q0, q1, t1, t2); MAX_DIFF2(t2, t1, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh); // Store _mm_storeu_si128((__m128i*)&p[-2 * stride], p1); _mm_storeu_si128((__m128i*)&p[-1 * stride], p0); _mm_storeu_si128((__m128i*)&p[0 * stride], q0); _mm_storeu_si128((__m128i*)&p[1 * stride], q1); } } static void HFilter16iSSE2(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { int k; uint8_t* b; __m128i mask; __m128i t1, t2, p1, p0, q0, q1; for (k = 3; k > 0; --k) { b = p; Load16x4(b, b + 8 * stride, stride, &t2, &t1, &p1, &p0); // p3, p2, p1, p0 MAX_DIFF1(t2, t1, p1, p0, mask); b += 4; // beginning of q0 Load16x4(b, b + 8 * stride, stride, &q0, &q1, &t1, &t2); // q0, q1, q2, q3 MAX_DIFF2(t2, t1, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh); b -= 2; // beginning of p1 Store16x4(b, b + 8 * stride, stride, &p1, &p0, &q0, &q1); p += 4; } } // 8-pixels wide variant, for chroma filtering static void VFilter8SSE2(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { __m128i mask; __m128i t1, p2, p1, p0, q0, q1, q2; // Load p3, p2, p1, p0 LOADUV_H_EDGES4(u - 4 * stride, v - 4 * stride, stride, t1, p2, p1, p0); MAX_DIFF1(t1, p2, p1, p0, mask); // Load q0, q1, q2, q3 LOADUV_H_EDGES4(u, v, stride, q0, q1, q2, t1); MAX_DIFF2(t1, q2, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh); // Store STOREUV(p2, u, v, -3 * stride); STOREUV(p1, u, v, -2 * stride); STOREUV(p0, u, v, -1 * stride); STOREUV(q0, u, v, 0 * stride); STOREUV(q1, u, v, 1 * stride); STOREUV(q2, u, v, 2 * stride); } static void HFilter8SSE2(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { __m128i mask; __m128i p3, p2, p1, p0, q0, q1, q2, q3; uint8_t* const tu = u - 4; uint8_t* const tv = v - 4; Load16x4(tu, tv, stride, &p3, &p2, &p1, &p0); // p3, p2, p1, p0 MAX_DIFF1(p3, p2, p1, p0, mask); Load16x4(u, v, stride, &q0, &q1, &q2, &q3); // q0, q1, q2, q3 MAX_DIFF2(q3, q2, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh); Store16x4(tu, tv, stride, &p3, &p2, &p1, &p0); Store16x4(u, v, stride, &q0, &q1, &q2, &q3); } static void VFilter8iSSE2(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { __m128i mask; __m128i t1, t2, p1, p0, q0, q1; // Load p3, p2, p1, p0 LOADUV_H_EDGES4(u, v, stride, t2, t1, p1, p0); MAX_DIFF1(t2, t1, p1, p0, mask); u += 4 * stride; v += 4 * stride; // Load q0, q1, q2, q3 LOADUV_H_EDGES4(u, v, stride, q0, q1, t1, t2); MAX_DIFF2(t2, t1, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh); // Store STOREUV(p1, u, v, -2 * stride); STOREUV(p0, u, v, -1 * stride); STOREUV(q0, u, v, 0 * stride); STOREUV(q1, u, v, 1 * stride); } static void HFilter8iSSE2(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { __m128i mask; __m128i t1, t2, p1, p0, q0, q1; Load16x4(u, v, stride, &t2, &t1, &p1, &p0); // p3, p2, p1, p0 MAX_DIFF1(t2, t1, p1, p0, mask); u += 4; // beginning of q0 v += 4; Load16x4(u, v, stride, &q0, &q1, &t1, &t2); // q0, q1, q2, q3 MAX_DIFF2(t2, t1, q1, q0, mask); COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask); DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh); u -= 2; // beginning of p1 v -= 2; Store16x4(u, v, stride, &p1, &p0, &q0, &q1); } #endif // WEBP_USE_SSE2 //------------------------------------------------------------------------------ // Entry point extern void VP8DspInitSSE2(void); void VP8DspInitSSE2(void) { #if defined(WEBP_USE_SSE2) VP8Transform = TransformSSE2; #if defined(USE_TRANSFORM_AC3) VP8TransformAC3 = TransformAC3SSE2; #endif VP8VFilter16 = VFilter16SSE2; VP8HFilter16 = HFilter16SSE2; VP8VFilter8 = VFilter8SSE2; VP8HFilter8 = HFilter8SSE2; VP8VFilter16i = VFilter16iSSE2; VP8HFilter16i = HFilter16iSSE2; VP8VFilter8i = VFilter8iSSE2; VP8HFilter8i = HFilter8iSSE2; VP8SimpleVFilter16 = SimpleVFilter16SSE2; VP8SimpleHFilter16 = SimpleHFilter16SSE2; VP8SimpleVFilter16i = SimpleVFilter16iSSE2; VP8SimpleHFilter16i = SimpleHFilter16iSSE2; #endif // WEBP_USE_SSE2 } libwebp-0.4.0/src/dsp/dec.c0000644000014400001440000005505112255002107012323 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Speed-critical decoding functions. // // Author: Skal (pascal.massimino@gmail.com) #include "./dsp.h" #include "../dec/vp8i.h" //------------------------------------------------------------------------------ // run-time tables (~4k) static uint8_t abs0[255 + 255 + 1]; // abs(i) static uint8_t abs1[255 + 255 + 1]; // abs(i)>>1 static int8_t sclip1[1020 + 1020 + 1]; // clips [-1020, 1020] to [-128, 127] static int8_t sclip2[112 + 112 + 1]; // clips [-112, 112] to [-16, 15] static uint8_t clip1[255 + 510 + 1]; // clips [-255,510] to [0,255] // We declare this variable 'volatile' to prevent instruction reordering // and make sure it's set to true _last_ (so as to be thread-safe) static volatile int tables_ok = 0; static void DspInitTables(void) { if (!tables_ok) { int i; for (i = -255; i <= 255; ++i) { abs0[255 + i] = (i < 0) ? -i : i; abs1[255 + i] = abs0[255 + i] >> 1; } for (i = -1020; i <= 1020; ++i) { sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i; } for (i = -112; i <= 112; ++i) { sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i; } for (i = -255; i <= 255 + 255; ++i) { clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i; } tables_ok = 1; } } static WEBP_INLINE uint8_t clip_8b(int v) { return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255; } //------------------------------------------------------------------------------ // Transforms (Paragraph 14.4) #define STORE(x, y, v) \ dst[x + y * BPS] = clip_8b(dst[x + y * BPS] + ((v) >> 3)) #define STORE2(y, dc, d, c) do { \ const int DC = (dc); \ STORE(0, y, DC + (d)); \ STORE(1, y, DC + (c)); \ STORE(2, y, DC - (c)); \ STORE(3, y, DC - (d)); \ } while (0) static const int kC1 = 20091 + (1 << 16); static const int kC2 = 35468; #define MUL(a, b) (((a) * (b)) >> 16) static void TransformOne(const int16_t* in, uint8_t* dst) { int C[4 * 4], *tmp; int i; tmp = C; for (i = 0; i < 4; ++i) { // vertical pass const int a = in[0] + in[8]; // [-4096, 4094] const int b = in[0] - in[8]; // [-4095, 4095] const int c = MUL(in[4], kC2) - MUL(in[12], kC1); // [-3783, 3783] const int d = MUL(in[4], kC1) + MUL(in[12], kC2); // [-3785, 3781] tmp[0] = a + d; // [-7881, 7875] tmp[1] = b + c; // [-7878, 7878] tmp[2] = b - c; // [-7878, 7878] tmp[3] = a - d; // [-7877, 7879] tmp += 4; in++; } // Each pass is expanding the dynamic range by ~3.85 (upper bound). // The exact value is (2. + (kC1 + kC2) / 65536). // After the second pass, maximum interval is [-3794, 3794], assuming // an input in [-2048, 2047] interval. We then need to add a dst value // in the [0, 255] range. // In the worst case scenario, the input to clip_8b() can be as large as // [-60713, 60968]. tmp = C; for (i = 0; i < 4; ++i) { // horizontal pass const int dc = tmp[0] + 4; const int a = dc + tmp[8]; const int b = dc - tmp[8]; const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1); const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2); STORE(0, 0, a + d); STORE(1, 0, b + c); STORE(2, 0, b - c); STORE(3, 0, a - d); tmp++; dst += BPS; } } // Simplified transform when only in[0], in[1] and in[4] are non-zero static void TransformAC3(const int16_t* in, uint8_t* dst) { const int a = in[0] + 4; const int c4 = MUL(in[4], kC2); const int d4 = MUL(in[4], kC1); const int c1 = MUL(in[1], kC2); const int d1 = MUL(in[1], kC1); STORE2(0, a + d4, d1, c1); STORE2(1, a + c4, d1, c1); STORE2(2, a - c4, d1, c1); STORE2(3, a - d4, d1, c1); } #undef MUL #undef STORE2 static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) { TransformOne(in, dst); if (do_two) { TransformOne(in + 16, dst + 4); } } static void TransformUV(const int16_t* in, uint8_t* dst) { VP8Transform(in + 0 * 16, dst, 1); VP8Transform(in + 2 * 16, dst + 4 * BPS, 1); } static void TransformDC(const int16_t *in, uint8_t* dst) { const int DC = in[0] + 4; int i, j; for (j = 0; j < 4; ++j) { for (i = 0; i < 4; ++i) { STORE(i, j, DC); } } } static void TransformDCUV(const int16_t* in, uint8_t* dst) { if (in[0 * 16]) TransformDC(in + 0 * 16, dst); if (in[1 * 16]) TransformDC(in + 1 * 16, dst + 4); if (in[2 * 16]) TransformDC(in + 2 * 16, dst + 4 * BPS); if (in[3 * 16]) TransformDC(in + 3 * 16, dst + 4 * BPS + 4); } #undef STORE //------------------------------------------------------------------------------ // Paragraph 14.3 static void TransformWHT(const int16_t* in, int16_t* out) { int tmp[16]; int i; for (i = 0; i < 4; ++i) { const int a0 = in[0 + i] + in[12 + i]; const int a1 = in[4 + i] + in[ 8 + i]; const int a2 = in[4 + i] - in[ 8 + i]; const int a3 = in[0 + i] - in[12 + i]; tmp[0 + i] = a0 + a1; tmp[8 + i] = a0 - a1; tmp[4 + i] = a3 + a2; tmp[12 + i] = a3 - a2; } for (i = 0; i < 4; ++i) { const int dc = tmp[0 + i * 4] + 3; // w/ rounder const int a0 = dc + tmp[3 + i * 4]; const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4]; const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4]; const int a3 = dc - tmp[3 + i * 4]; out[ 0] = (a0 + a1) >> 3; out[16] = (a3 + a2) >> 3; out[32] = (a0 - a1) >> 3; out[48] = (a3 - a2) >> 3; out += 64; } } void (*VP8TransformWHT)(const int16_t* in, int16_t* out) = TransformWHT; //------------------------------------------------------------------------------ // Intra predictions #define DST(x, y) dst[(x) + (y) * BPS] static WEBP_INLINE void TrueMotion(uint8_t *dst, int size) { const uint8_t* top = dst - BPS; const uint8_t* const clip0 = clip1 + 255 - top[-1]; int y; for (y = 0; y < size; ++y) { const uint8_t* const clip = clip0 + dst[-1]; int x; for (x = 0; x < size; ++x) { dst[x] = clip[top[x]]; } dst += BPS; } } static void TM4(uint8_t *dst) { TrueMotion(dst, 4); } static void TM8uv(uint8_t *dst) { TrueMotion(dst, 8); } static void TM16(uint8_t *dst) { TrueMotion(dst, 16); } //------------------------------------------------------------------------------ // 16x16 static void VE16(uint8_t *dst) { // vertical int j; for (j = 0; j < 16; ++j) { memcpy(dst + j * BPS, dst - BPS, 16); } } static void HE16(uint8_t *dst) { // horizontal int j; for (j = 16; j > 0; --j) { memset(dst, dst[-1], 16); dst += BPS; } } static WEBP_INLINE void Put16(int v, uint8_t* dst) { int j; for (j = 0; j < 16; ++j) { memset(dst + j * BPS, v, 16); } } static void DC16(uint8_t *dst) { // DC int DC = 16; int j; for (j = 0; j < 16; ++j) { DC += dst[-1 + j * BPS] + dst[j - BPS]; } Put16(DC >> 5, dst); } static void DC16NoTop(uint8_t *dst) { // DC with top samples not available int DC = 8; int j; for (j = 0; j < 16; ++j) { DC += dst[-1 + j * BPS]; } Put16(DC >> 4, dst); } static void DC16NoLeft(uint8_t *dst) { // DC with left samples not available int DC = 8; int i; for (i = 0; i < 16; ++i) { DC += dst[i - BPS]; } Put16(DC >> 4, dst); } static void DC16NoTopLeft(uint8_t *dst) { // DC with no top and left samples Put16(0x80, dst); } //------------------------------------------------------------------------------ // 4x4 #define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2) #define AVG2(a, b) (((a) + (b) + 1) >> 1) static void VE4(uint8_t *dst) { // vertical const uint8_t* top = dst - BPS; const uint8_t vals[4] = { AVG3(top[-1], top[0], top[1]), AVG3(top[ 0], top[1], top[2]), AVG3(top[ 1], top[2], top[3]), AVG3(top[ 2], top[3], top[4]) }; int i; for (i = 0; i < 4; ++i) { memcpy(dst + i * BPS, vals, sizeof(vals)); } } static void HE4(uint8_t *dst) { // horizontal const int A = dst[-1 - BPS]; const int B = dst[-1]; const int C = dst[-1 + BPS]; const int D = dst[-1 + 2 * BPS]; const int E = dst[-1 + 3 * BPS]; *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(A, B, C); *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(B, C, D); *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(C, D, E); *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(D, E, E); } static void DC4(uint8_t *dst) { // DC uint32_t dc = 4; int i; for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS]; dc >>= 3; for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4); } static void RD4(uint8_t *dst) { // Down-right const int I = dst[-1 + 0 * BPS]; const int J = dst[-1 + 1 * BPS]; const int K = dst[-1 + 2 * BPS]; const int L = dst[-1 + 3 * BPS]; const int X = dst[-1 - BPS]; const int A = dst[0 - BPS]; const int B = dst[1 - BPS]; const int C = dst[2 - BPS]; const int D = dst[3 - BPS]; DST(0, 3) = AVG3(J, K, L); DST(0, 2) = DST(1, 3) = AVG3(I, J, K); DST(0, 1) = DST(1, 2) = DST(2, 3) = AVG3(X, I, J); DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I); DST(1, 0) = DST(2, 1) = DST(3, 2) = AVG3(B, A, X); DST(2, 0) = DST(3, 1) = AVG3(C, B, A); DST(3, 0) = AVG3(D, C, B); } static void LD4(uint8_t *dst) { // Down-Left const int A = dst[0 - BPS]; const int B = dst[1 - BPS]; const int C = dst[2 - BPS]; const int D = dst[3 - BPS]; const int E = dst[4 - BPS]; const int F = dst[5 - BPS]; const int G = dst[6 - BPS]; const int H = dst[7 - BPS]; DST(0, 0) = AVG3(A, B, C); DST(1, 0) = DST(0, 1) = AVG3(B, C, D); DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E); DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F); DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G); DST(3, 2) = DST(2, 3) = AVG3(F, G, H); DST(3, 3) = AVG3(G, H, H); } static void VR4(uint8_t *dst) { // Vertical-Right const int I = dst[-1 + 0 * BPS]; const int J = dst[-1 + 1 * BPS]; const int K = dst[-1 + 2 * BPS]; const int X = dst[-1 - BPS]; const int A = dst[0 - BPS]; const int B = dst[1 - BPS]; const int C = dst[2 - BPS]; const int D = dst[3 - BPS]; DST(0, 0) = DST(1, 2) = AVG2(X, A); DST(1, 0) = DST(2, 2) = AVG2(A, B); DST(2, 0) = DST(3, 2) = AVG2(B, C); DST(3, 0) = AVG2(C, D); DST(0, 3) = AVG3(K, J, I); DST(0, 2) = AVG3(J, I, X); DST(0, 1) = DST(1, 3) = AVG3(I, X, A); DST(1, 1) = DST(2, 3) = AVG3(X, A, B); DST(2, 1) = DST(3, 3) = AVG3(A, B, C); DST(3, 1) = AVG3(B, C, D); } static void VL4(uint8_t *dst) { // Vertical-Left const int A = dst[0 - BPS]; const int B = dst[1 - BPS]; const int C = dst[2 - BPS]; const int D = dst[3 - BPS]; const int E = dst[4 - BPS]; const int F = dst[5 - BPS]; const int G = dst[6 - BPS]; const int H = dst[7 - BPS]; DST(0, 0) = AVG2(A, B); DST(1, 0) = DST(0, 2) = AVG2(B, C); DST(2, 0) = DST(1, 2) = AVG2(C, D); DST(3, 0) = DST(2, 2) = AVG2(D, E); DST(0, 1) = AVG3(A, B, C); DST(1, 1) = DST(0, 3) = AVG3(B, C, D); DST(2, 1) = DST(1, 3) = AVG3(C, D, E); DST(3, 1) = DST(2, 3) = AVG3(D, E, F); DST(3, 2) = AVG3(E, F, G); DST(3, 3) = AVG3(F, G, H); } static void HU4(uint8_t *dst) { // Horizontal-Up const int I = dst[-1 + 0 * BPS]; const int J = dst[-1 + 1 * BPS]; const int K = dst[-1 + 2 * BPS]; const int L = dst[-1 + 3 * BPS]; DST(0, 0) = AVG2(I, J); DST(2, 0) = DST(0, 1) = AVG2(J, K); DST(2, 1) = DST(0, 2) = AVG2(K, L); DST(1, 0) = AVG3(I, J, K); DST(3, 0) = DST(1, 1) = AVG3(J, K, L); DST(3, 1) = DST(1, 2) = AVG3(K, L, L); DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L; } static void HD4(uint8_t *dst) { // Horizontal-Down const int I = dst[-1 + 0 * BPS]; const int J = dst[-1 + 1 * BPS]; const int K = dst[-1 + 2 * BPS]; const int L = dst[-1 + 3 * BPS]; const int X = dst[-1 - BPS]; const int A = dst[0 - BPS]; const int B = dst[1 - BPS]; const int C = dst[2 - BPS]; DST(0, 0) = DST(2, 1) = AVG2(I, X); DST(0, 1) = DST(2, 2) = AVG2(J, I); DST(0, 2) = DST(2, 3) = AVG2(K, J); DST(0, 3) = AVG2(L, K); DST(3, 0) = AVG3(A, B, C); DST(2, 0) = AVG3(X, A, B); DST(1, 0) = DST(3, 1) = AVG3(I, X, A); DST(1, 1) = DST(3, 2) = AVG3(J, I, X); DST(1, 2) = DST(3, 3) = AVG3(K, J, I); DST(1, 3) = AVG3(L, K, J); } #undef DST #undef AVG3 #undef AVG2 //------------------------------------------------------------------------------ // Chroma static void VE8uv(uint8_t *dst) { // vertical int j; for (j = 0; j < 8; ++j) { memcpy(dst + j * BPS, dst - BPS, 8); } } static void HE8uv(uint8_t *dst) { // horizontal int j; for (j = 0; j < 8; ++j) { memset(dst, dst[-1], 8); dst += BPS; } } // helper for chroma-DC predictions static WEBP_INLINE void Put8x8uv(uint8_t value, uint8_t* dst) { int j; #ifndef WEBP_REFERENCE_IMPLEMENTATION const uint64_t v = (uint64_t)value * 0x0101010101010101ULL; for (j = 0; j < 8; ++j) { *(uint64_t*)(dst + j * BPS) = v; } #else for (j = 0; j < 8; ++j) memset(dst + j * BPS, value, 8); #endif } static void DC8uv(uint8_t *dst) { // DC int dc0 = 8; int i; for (i = 0; i < 8; ++i) { dc0 += dst[i - BPS] + dst[-1 + i * BPS]; } Put8x8uv(dc0 >> 4, dst); } static void DC8uvNoLeft(uint8_t *dst) { // DC with no left samples int dc0 = 4; int i; for (i = 0; i < 8; ++i) { dc0 += dst[i - BPS]; } Put8x8uv(dc0 >> 3, dst); } static void DC8uvNoTop(uint8_t *dst) { // DC with no top samples int dc0 = 4; int i; for (i = 0; i < 8; ++i) { dc0 += dst[-1 + i * BPS]; } Put8x8uv(dc0 >> 3, dst); } static void DC8uvNoTopLeft(uint8_t *dst) { // DC with nothing Put8x8uv(0x80, dst); } //------------------------------------------------------------------------------ // default C implementations const VP8PredFunc VP8PredLuma4[NUM_BMODES] = { DC4, TM4, VE4, HE4, RD4, VR4, LD4, VL4, HD4, HU4 }; const VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES] = { DC16, TM16, VE16, HE16, DC16NoTop, DC16NoLeft, DC16NoTopLeft }; const VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES] = { DC8uv, TM8uv, VE8uv, HE8uv, DC8uvNoTop, DC8uvNoLeft, DC8uvNoTopLeft }; //------------------------------------------------------------------------------ // Edge filtering functions // 4 pixels in, 2 pixels out static WEBP_INLINE void do_filter2(uint8_t* p, int step) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; const int a = 3 * (q0 - p0) + sclip1[1020 + p1 - q1]; const int a1 = sclip2[112 + ((a + 4) >> 3)]; const int a2 = sclip2[112 + ((a + 3) >> 3)]; p[-step] = clip1[255 + p0 + a2]; p[ 0] = clip1[255 + q0 - a1]; } // 4 pixels in, 4 pixels out static WEBP_INLINE void do_filter4(uint8_t* p, int step) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; const int a = 3 * (q0 - p0); const int a1 = sclip2[112 + ((a + 4) >> 3)]; const int a2 = sclip2[112 + ((a + 3) >> 3)]; const int a3 = (a1 + 1) >> 1; p[-2*step] = clip1[255 + p1 + a3]; p[- step] = clip1[255 + p0 + a2]; p[ 0] = clip1[255 + q0 - a1]; p[ step] = clip1[255 + q1 - a3]; } // 6 pixels in, 6 pixels out static WEBP_INLINE void do_filter6(uint8_t* p, int step) { const int p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step]; const int q0 = p[0], q1 = p[step], q2 = p[2*step]; const int a = sclip1[1020 + 3 * (q0 - p0) + sclip1[1020 + p1 - q1]]; const int a1 = (27 * a + 63) >> 7; // eq. to ((3 * a + 7) * 9) >> 7 const int a2 = (18 * a + 63) >> 7; // eq. to ((2 * a + 7) * 9) >> 7 const int a3 = (9 * a + 63) >> 7; // eq. to ((1 * a + 7) * 9) >> 7 p[-3*step] = clip1[255 + p2 + a3]; p[-2*step] = clip1[255 + p1 + a2]; p[- step] = clip1[255 + p0 + a1]; p[ 0] = clip1[255 + q0 - a1]; p[ step] = clip1[255 + q1 - a2]; p[ 2*step] = clip1[255 + q2 - a3]; } static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; return (abs0[255 + p1 - p0] > thresh) || (abs0[255 + q1 - q0] > thresh); } static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int thresh) { const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step]; return (2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) <= thresh; } static WEBP_INLINE int needs_filter2(const uint8_t* p, int step, int t, int it) { const int p3 = p[-4*step], p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step]; const int q0 = p[0], q1 = p[step], q2 = p[2*step], q3 = p[3*step]; if ((2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) > t) return 0; return abs0[255 + p3 - p2] <= it && abs0[255 + p2 - p1] <= it && abs0[255 + p1 - p0] <= it && abs0[255 + q3 - q2] <= it && abs0[255 + q2 - q1] <= it && abs0[255 + q1 - q0] <= it; } //------------------------------------------------------------------------------ // Simple In-loop filtering (Paragraph 15.2) static void SimpleVFilter16(uint8_t* p, int stride, int thresh) { int i; for (i = 0; i < 16; ++i) { if (needs_filter(p + i, stride, thresh)) { do_filter2(p + i, stride); } } } static void SimpleHFilter16(uint8_t* p, int stride, int thresh) { int i; for (i = 0; i < 16; ++i) { if (needs_filter(p + i * stride, 1, thresh)) { do_filter2(p + i * stride, 1); } } } static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4 * stride; SimpleVFilter16(p, stride, thresh); } } static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4; SimpleHFilter16(p, stride, thresh); } } //------------------------------------------------------------------------------ // Complex In-loop filtering (Paragraph 15.3) static WEBP_INLINE void FilterLoop26(uint8_t* p, int hstride, int vstride, int size, int thresh, int ithresh, int hev_thresh) { while (size-- > 0) { if (needs_filter2(p, hstride, thresh, ithresh)) { if (hev(p, hstride, hev_thresh)) { do_filter2(p, hstride); } else { do_filter6(p, hstride); } } p += vstride; } } static WEBP_INLINE void FilterLoop24(uint8_t* p, int hstride, int vstride, int size, int thresh, int ithresh, int hev_thresh) { while (size-- > 0) { if (needs_filter2(p, hstride, thresh, ithresh)) { if (hev(p, hstride, hev_thresh)) { do_filter2(p, hstride); } else { do_filter4(p, hstride); } } p += vstride; } } // on macroblock edges static void VFilter16(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh); } static void HFilter16(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh); } // on three inner edges static void VFilter16i(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { int k; for (k = 3; k > 0; --k) { p += 4 * stride; FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh); } } static void HFilter16i(uint8_t* p, int stride, int thresh, int ithresh, int hev_thresh) { int k; for (k = 3; k > 0; --k) { p += 4; FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh); } } // 8-pixels wide variant, for chroma filtering static void VFilter8(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh); FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh); } static void HFilter8(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh); } static void VFilter8i(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh); FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh); } static void HFilter8i(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_thresh) { FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh); } //------------------------------------------------------------------------------ VP8DecIdct2 VP8Transform; VP8DecIdct VP8TransformAC3; VP8DecIdct VP8TransformUV; VP8DecIdct VP8TransformDC; VP8DecIdct VP8TransformDCUV; VP8LumaFilterFunc VP8VFilter16; VP8LumaFilterFunc VP8HFilter16; VP8ChromaFilterFunc VP8VFilter8; VP8ChromaFilterFunc VP8HFilter8; VP8LumaFilterFunc VP8VFilter16i; VP8LumaFilterFunc VP8HFilter16i; VP8ChromaFilterFunc VP8VFilter8i; VP8ChromaFilterFunc VP8HFilter8i; VP8SimpleFilterFunc VP8SimpleVFilter16; VP8SimpleFilterFunc VP8SimpleHFilter16; VP8SimpleFilterFunc VP8SimpleVFilter16i; VP8SimpleFilterFunc VP8SimpleHFilter16i; extern void VP8DspInitSSE2(void); extern void VP8DspInitNEON(void); void VP8DspInit(void) { DspInitTables(); VP8Transform = TransformTwo; VP8TransformUV = TransformUV; VP8TransformDC = TransformDC; VP8TransformDCUV = TransformDCUV; VP8TransformAC3 = TransformAC3; VP8VFilter16 = VFilter16; VP8HFilter16 = HFilter16; VP8VFilter8 = VFilter8; VP8HFilter8 = HFilter8; VP8VFilter16i = VFilter16i; VP8HFilter16i = HFilter16i; VP8VFilter8i = VFilter8i; VP8HFilter8i = HFilter8i; VP8SimpleVFilter16 = SimpleVFilter16; VP8SimpleHFilter16 = SimpleHFilter16; VP8SimpleVFilter16i = SimpleVFilter16i; VP8SimpleHFilter16i = SimpleHFilter16i; // If defined, use CPUInfo() to overwrite some pointers with faster versions. if (VP8GetCPUInfo) { #if defined(WEBP_USE_SSE2) if (VP8GetCPUInfo(kSSE2)) { VP8DspInitSSE2(); } #elif defined(WEBP_USE_NEON) if (VP8GetCPUInfo(kNEON)) { VP8DspInitNEON(); } #endif } } libwebp-0.4.0/src/dsp/upsampling_neon.c0000644000014400001440000003434112255002107014765 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // NEON version of YUV to RGB upsampling functions. // // Author: mans@mansr.com (Mans Rullgard) // Based on SSE code by: somnath@google.com (Somnath Banerjee) #include "./dsp.h" #if defined(WEBP_USE_NEON) #include #include #include #include "./yuv.h" #ifdef FANCY_UPSAMPLING //----------------------------------------------------------------------------- // U/V upsampling // Loads 9 pixels each from rows r1 and r2 and generates 16 pixels. #define UPSAMPLE_16PIXELS(r1, r2, out) { \ uint8x8_t a = vld1_u8(r1); \ uint8x8_t b = vld1_u8(r1 + 1); \ uint8x8_t c = vld1_u8(r2); \ uint8x8_t d = vld1_u8(r2 + 1); \ \ uint16x8_t al = vshll_n_u8(a, 1); \ uint16x8_t bl = vshll_n_u8(b, 1); \ uint16x8_t cl = vshll_n_u8(c, 1); \ uint16x8_t dl = vshll_n_u8(d, 1); \ \ uint8x8_t diag1, diag2; \ uint16x8_t sl; \ \ /* a + b + c + d */ \ sl = vaddl_u8(a, b); \ sl = vaddw_u8(sl, c); \ sl = vaddw_u8(sl, d); \ \ al = vaddq_u16(sl, al); /* 3a + b + c + d */ \ bl = vaddq_u16(sl, bl); /* a + 3b + c + d */ \ \ al = vaddq_u16(al, dl); /* 3a + b + c + 3d */ \ bl = vaddq_u16(bl, cl); /* a + 3b + 3c + d */ \ \ diag2 = vshrn_n_u16(al, 3); \ diag1 = vshrn_n_u16(bl, 3); \ \ a = vrhadd_u8(a, diag1); \ b = vrhadd_u8(b, diag2); \ c = vrhadd_u8(c, diag2); \ d = vrhadd_u8(d, diag1); \ \ { \ const uint8x8x2_t a_b = {{ a, b }}; \ const uint8x8x2_t c_d = {{ c, d }}; \ vst2_u8(out, a_b); \ vst2_u8(out + 32, c_d); \ } \ } // Turn the macro into a function for reducing code-size when non-critical static void Upsample16Pixels(const uint8_t *r1, const uint8_t *r2, uint8_t *out) { UPSAMPLE_16PIXELS(r1, r2, out); } #define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) { \ uint8_t r1[9], r2[9]; \ memcpy(r1, (tb), (num_pixels)); \ memcpy(r2, (bb), (num_pixels)); \ /* replicate last byte */ \ memset(r1 + (num_pixels), r1[(num_pixels) - 1], 9 - (num_pixels)); \ memset(r2 + (num_pixels), r2[(num_pixels) - 1], 9 - (num_pixels)); \ Upsample16Pixels(r1, r2, out); \ } //----------------------------------------------------------------------------- // YUV->RGB conversion static const int16_t kCoeffs[4] = { kYScale, kVToR, kUToG, kVToG }; #define v255 vmov_n_u8(255) #define STORE_Rgb(out, r, g, b) do { \ const uint8x8x3_t r_g_b = {{ r, g, b }}; \ vst3_u8(out, r_g_b); \ } while (0) #define STORE_Bgr(out, r, g, b) do { \ const uint8x8x3_t b_g_r = {{ b, g, r }}; \ vst3_u8(out, b_g_r); \ } while (0) #define STORE_Rgba(out, r, g, b) do { \ const uint8x8x4_t r_g_b_v255 = {{ r, g, b, v255 }}; \ vst4_u8(out, r_g_b_v255); \ } while (0) #define STORE_Bgra(out, r, g, b) do { \ const uint8x8x4_t b_g_r_v255 = {{ b, g, r, v255 }}; \ vst4_u8(out, b_g_r_v255); \ } while (0) #define CONVERT8(FMT, XSTEP, N, src_y, src_uv, out, cur_x) { \ int i; \ for (i = 0; i < N; i += 8) { \ const int off = ((cur_x) + i) * XSTEP; \ uint8x8_t y = vld1_u8((src_y) + (cur_x) + i); \ uint8x8_t u = vld1_u8((src_uv) + i); \ uint8x8_t v = vld1_u8((src_uv) + i + 16); \ const int16x8_t yy = vreinterpretq_s16_u16(vsubl_u8(y, u16)); \ const int16x8_t uu = vreinterpretq_s16_u16(vsubl_u8(u, u128)); \ const int16x8_t vv = vreinterpretq_s16_u16(vsubl_u8(v, u128)); \ int32x4_t yl = vmull_lane_s16(vget_low_s16(yy), cf16, 0); \ int32x4_t yh = vmull_lane_s16(vget_high_s16(yy), cf16, 0); \ const int32x4_t rl = vmlal_lane_s16(yl, vget_low_s16(vv), cf16, 1);\ const int32x4_t rh = vmlal_lane_s16(yh, vget_high_s16(vv), cf16, 1);\ int32x4_t gl = vmlsl_lane_s16(yl, vget_low_s16(uu), cf16, 2); \ int32x4_t gh = vmlsl_lane_s16(yh, vget_high_s16(uu), cf16, 2); \ const int32x4_t bl = vmovl_s16(vget_low_s16(uu)); \ const int32x4_t bh = vmovl_s16(vget_high_s16(uu)); \ gl = vmlsl_lane_s16(gl, vget_low_s16(vv), cf16, 3); \ gh = vmlsl_lane_s16(gh, vget_high_s16(vv), cf16, 3); \ yl = vmlaq_lane_s32(yl, bl, cf32, 0); \ yh = vmlaq_lane_s32(yh, bh, cf32, 0); \ /* vrshrn_n_s32() already incorporates the rounding constant */ \ y = vqmovun_s16(vcombine_s16(vrshrn_n_s32(rl, YUV_FIX2), \ vrshrn_n_s32(rh, YUV_FIX2))); \ u = vqmovun_s16(vcombine_s16(vrshrn_n_s32(gl, YUV_FIX2), \ vrshrn_n_s32(gh, YUV_FIX2))); \ v = vqmovun_s16(vcombine_s16(vrshrn_n_s32(yl, YUV_FIX2), \ vrshrn_n_s32(yh, YUV_FIX2))); \ STORE_ ## FMT(out + off, y, u, v); \ } \ } #define CONVERT1(FUNC, XSTEP, N, src_y, src_uv, rgb, cur_x) { \ int i; \ for (i = 0; i < N; i++) { \ const int off = ((cur_x) + i) * XSTEP; \ const int y = src_y[(cur_x) + i]; \ const int u = (src_uv)[i]; \ const int v = (src_uv)[i + 16]; \ FUNC(y, u, v, rgb + off); \ } \ } #define CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, uv, \ top_dst, bottom_dst, cur_x, len) { \ CONVERT8(FMT, XSTEP, len, top_y, uv, top_dst, cur_x) \ if (bottom_y != NULL) { \ CONVERT8(FMT, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x) \ } \ } #define CONVERT2RGB_1(FUNC, XSTEP, top_y, bottom_y, uv, \ top_dst, bottom_dst, cur_x, len) { \ CONVERT1(FUNC, XSTEP, len, top_y, uv, top_dst, cur_x); \ if (bottom_y != NULL) { \ CONVERT1(FUNC, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x); \ } \ } #define NEON_UPSAMPLE_FUNC(FUNC_NAME, FMT, XSTEP) \ static void FUNC_NAME(const uint8_t *top_y, const uint8_t *bottom_y, \ const uint8_t *top_u, const uint8_t *top_v, \ const uint8_t *cur_u, const uint8_t *cur_v, \ uint8_t *top_dst, uint8_t *bottom_dst, int len) { \ int block; \ /* 16 byte aligned array to cache reconstructed u and v */ \ uint8_t uv_buf[2 * 32 + 15]; \ uint8_t *const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \ const int uv_len = (len + 1) >> 1; \ /* 9 pixels must be read-able for each block */ \ const int num_blocks = (uv_len - 1) >> 3; \ const int leftover = uv_len - num_blocks * 8; \ const int last_pos = 1 + 16 * num_blocks; \ \ const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1; \ const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1; \ \ const int16x4_t cf16 = vld1_s16(kCoeffs); \ const int32x2_t cf32 = vmov_n_s32(kUToB); \ const uint8x8_t u16 = vmov_n_u8(16); \ const uint8x8_t u128 = vmov_n_u8(128); \ \ /* Treat the first pixel in regular way */ \ assert(top_y != NULL); \ { \ const int u0 = (top_u[0] + u_diag) >> 1; \ const int v0 = (top_v[0] + v_diag) >> 1; \ VP8YuvTo ## FMT(top_y[0], u0, v0, top_dst); \ } \ if (bottom_y != NULL) { \ const int u0 = (cur_u[0] + u_diag) >> 1; \ const int v0 = (cur_v[0] + v_diag) >> 1; \ VP8YuvTo ## FMT(bottom_y[0], u0, v0, bottom_dst); \ } \ \ for (block = 0; block < num_blocks; ++block) { \ UPSAMPLE_16PIXELS(top_u, cur_u, r_uv); \ UPSAMPLE_16PIXELS(top_v, cur_v, r_uv + 16); \ CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, r_uv, \ top_dst, bottom_dst, 16 * block + 1, 16); \ top_u += 8; \ cur_u += 8; \ top_v += 8; \ cur_v += 8; \ } \ \ UPSAMPLE_LAST_BLOCK(top_u, cur_u, leftover, r_uv); \ UPSAMPLE_LAST_BLOCK(top_v, cur_v, leftover, r_uv + 16); \ CONVERT2RGB_1(VP8YuvTo ## FMT, XSTEP, top_y, bottom_y, r_uv, \ top_dst, bottom_dst, last_pos, len - last_pos); \ } // NEON variants of the fancy upsampler. NEON_UPSAMPLE_FUNC(UpsampleRgbLinePairNEON, Rgb, 3) NEON_UPSAMPLE_FUNC(UpsampleBgrLinePairNEON, Bgr, 3) NEON_UPSAMPLE_FUNC(UpsampleRgbaLinePairNEON, Rgba, 4) NEON_UPSAMPLE_FUNC(UpsampleBgraLinePairNEON, Bgra, 4) #endif // FANCY_UPSAMPLING #endif // WEBP_USE_NEON //------------------------------------------------------------------------------ #ifdef FANCY_UPSAMPLING extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */]; void WebPInitUpsamplersNEON(void) { #if defined(WEBP_USE_NEON) WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePairNEON; WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePairNEON; WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePairNEON; WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePairNEON; #endif // WEBP_USE_NEON } void WebPInitPremultiplyNEON(void) { #if defined(WEBP_USE_NEON) WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePairNEON; WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePairNEON; #endif // WEBP_USE_NEON } #else // this empty function is to avoid an empty .o void WebPInitPremultiplyNEON(void) {} #endif // FANCY_UPSAMPLING libwebp-0.4.0/src/dsp/lossless.c0000644000014400001440000016667512255002107013456 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Image transforms and color space conversion methods for lossless decoder. // // Authors: Vikas Arora (vikaas.arora@gmail.com) // Jyrki Alakuijala (jyrki@google.com) // Urvang Joshi (urvang@google.com) #include "./dsp.h" #if defined(WEBP_USE_SSE2) #include #endif #include #include #include "./lossless.h" #include "../dec/vp8li.h" #include "./yuv.h" #define MAX_DIFF_COST (1e30f) // lookup table for small values of log2(int) #define APPROX_LOG_MAX 4096 #define LOG_2_RECIPROCAL 1.44269504088896338700465094007086 const float kLog2Table[LOG_LOOKUP_IDX_MAX] = { 0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f, 1.5849625007211560f, 2.0000000000000000f, 2.3219280948873621f, 2.5849625007211560f, 2.8073549220576041f, 3.0000000000000000f, 3.1699250014423121f, 3.3219280948873621f, 3.4594316186372973f, 3.5849625007211560f, 3.7004397181410921f, 3.8073549220576041f, 3.9068905956085187f, 4.0000000000000000f, 4.0874628412503390f, 4.1699250014423121f, 4.2479275134435852f, 4.3219280948873626f, 4.3923174227787606f, 4.4594316186372973f, 4.5235619560570130f, 4.5849625007211560f, 4.6438561897747243f, 4.7004397181410917f, 4.7548875021634682f, 4.8073549220576037f, 4.8579809951275718f, 4.9068905956085187f, 4.9541963103868749f, 5.0000000000000000f, 5.0443941193584533f, 5.0874628412503390f, 5.1292830169449663f, 5.1699250014423121f, 5.2094533656289501f, 5.2479275134435852f, 5.2854022188622487f, 5.3219280948873626f, 5.3575520046180837f, 5.3923174227787606f, 5.4262647547020979f, 5.4594316186372973f, 5.4918530963296747f, 5.5235619560570130f, 5.5545888516776376f, 5.5849625007211560f, 5.6147098441152083f, 5.6438561897747243f, 5.6724253419714951f, 5.7004397181410917f, 5.7279204545631987f, 5.7548875021634682f, 5.7813597135246599f, 5.8073549220576037f, 5.8328900141647412f, 5.8579809951275718f, 5.8826430493618415f, 5.9068905956085187f, 5.9307373375628866f, 5.9541963103868749f, 5.9772799234999167f, 6.0000000000000000f, 6.0223678130284543f, 6.0443941193584533f, 6.0660891904577720f, 6.0874628412503390f, 6.1085244567781691f, 6.1292830169449663f, 6.1497471195046822f, 6.1699250014423121f, 6.1898245588800175f, 6.2094533656289501f, 6.2288186904958804f, 6.2479275134435852f, 6.2667865406949010f, 6.2854022188622487f, 6.3037807481771030f, 6.3219280948873626f, 6.3398500028846243f, 6.3575520046180837f, 6.3750394313469245f, 6.3923174227787606f, 6.4093909361377017f, 6.4262647547020979f, 6.4429434958487279f, 6.4594316186372973f, 6.4757334309663976f, 6.4918530963296747f, 6.5077946401986963f, 6.5235619560570130f, 6.5391588111080309f, 6.5545888516776376f, 6.5698556083309478f, 6.5849625007211560f, 6.5999128421871278f, 6.6147098441152083f, 6.6293566200796094f, 6.6438561897747243f, 6.6582114827517946f, 6.6724253419714951f, 6.6865005271832185f, 6.7004397181410917f, 6.7142455176661224f, 6.7279204545631987f, 6.7414669864011464f, 6.7548875021634682f, 6.7681843247769259f, 6.7813597135246599f, 6.7944158663501061f, 6.8073549220576037f, 6.8201789624151878f, 6.8328900141647412f, 6.8454900509443747f, 6.8579809951275718f, 6.8703647195834047f, 6.8826430493618415f, 6.8948177633079437f, 6.9068905956085187f, 6.9188632372745946f, 6.9307373375628866f, 6.9425145053392398f, 6.9541963103868749f, 6.9657842846620869f, 6.9772799234999167f, 6.9886846867721654f, 7.0000000000000000f, 7.0112272554232539f, 7.0223678130284543f, 7.0334230015374501f, 7.0443941193584533f, 7.0552824355011898f, 7.0660891904577720f, 7.0768155970508308f, 7.0874628412503390f, 7.0980320829605263f, 7.1085244567781691f, 7.1189410727235076f, 7.1292830169449663f, 7.1395513523987936f, 7.1497471195046822f, 7.1598713367783890f, 7.1699250014423121f, 7.1799090900149344f, 7.1898245588800175f, 7.1996723448363644f, 7.2094533656289501f, 7.2191685204621611f, 7.2288186904958804f, 7.2384047393250785f, 7.2479275134435852f, 7.2573878426926521f, 7.2667865406949010f, 7.2761244052742375f, 7.2854022188622487f, 7.2946207488916270f, 7.3037807481771030f, 7.3128829552843557f, 7.3219280948873626f, 7.3309168781146167f, 7.3398500028846243f, 7.3487281542310771f, 7.3575520046180837f, 7.3663222142458160f, 7.3750394313469245f, 7.3837042924740519f, 7.3923174227787606f, 7.4008794362821843f, 7.4093909361377017f, 7.4178525148858982f, 7.4262647547020979f, 7.4346282276367245f, 7.4429434958487279f, 7.4512111118323289f, 7.4594316186372973f, 7.4676055500829976f, 7.4757334309663976f, 7.4838157772642563f, 7.4918530963296747f, 7.4998458870832056f, 7.5077946401986963f, 7.5156998382840427f, 7.5235619560570130f, 7.5313814605163118f, 7.5391588111080309f, 7.5468944598876364f, 7.5545888516776376f, 7.5622424242210728f, 7.5698556083309478f, 7.5774288280357486f, 7.5849625007211560f, 7.5924570372680806f, 7.5999128421871278f, 7.6073303137496104f, 7.6147098441152083f, 7.6220518194563764f, 7.6293566200796094f, 7.6366246205436487f, 7.6438561897747243f, 7.6510516911789281f, 7.6582114827517946f, 7.6653359171851764f, 7.6724253419714951f, 7.6794800995054464f, 7.6865005271832185f, 7.6934869574993252f, 7.7004397181410917f, 7.7073591320808825f, 7.7142455176661224f, 7.7210991887071855f, 7.7279204545631987f, 7.7347096202258383f, 7.7414669864011464f, 7.7481928495894605f, 7.7548875021634682f, 7.7615512324444795f, 7.7681843247769259f, 7.7747870596011736f, 7.7813597135246599f, 7.7879025593914317f, 7.7944158663501061f, 7.8008998999203047f, 7.8073549220576037f, 7.8137811912170374f, 7.8201789624151878f, 7.8265484872909150f, 7.8328900141647412f, 7.8392037880969436f, 7.8454900509443747f, 7.8517490414160571f, 7.8579809951275718f, 7.8641861446542797f, 7.8703647195834047f, 7.8765169465649993f, 7.8826430493618415f, 7.8887432488982591f, 7.8948177633079437f, 7.9008668079807486f, 7.9068905956085187f, 7.9128893362299619f, 7.9188632372745946f, 7.9248125036057812f, 7.9307373375628866f, 7.9366379390025709f, 7.9425145053392398f, 7.9483672315846778f, 7.9541963103868749f, 7.9600019320680805f, 7.9657842846620869f, 7.9715435539507719f, 7.9772799234999167f, 7.9829935746943103f, 7.9886846867721654f, 7.9943534368588577f }; const float kSLog2Table[LOG_LOOKUP_IDX_MAX] = { 0.00000000f, 0.00000000f, 2.00000000f, 4.75488750f, 8.00000000f, 11.60964047f, 15.50977500f, 19.65148445f, 24.00000000f, 28.52932501f, 33.21928095f, 38.05374781f, 43.01955001f, 48.10571634f, 53.30296891f, 58.60335893f, 64.00000000f, 69.48686830f, 75.05865003f, 80.71062276f, 86.43856190f, 92.23866588f, 98.10749561f, 104.04192499f, 110.03910002f, 116.09640474f, 122.21143267f, 128.38196256f, 134.60593782f, 140.88144886f, 147.20671787f, 153.58008562f, 160.00000000f, 166.46500594f, 172.97373660f, 179.52490559f, 186.11730005f, 192.74977453f, 199.42124551f, 206.13068654f, 212.87712380f, 219.65963219f, 226.47733176f, 233.32938445f, 240.21499122f, 247.13338933f, 254.08384998f, 261.06567603f, 268.07820003f, 275.12078236f, 282.19280949f, 289.29369244f, 296.42286534f, 303.57978409f, 310.76392512f, 317.97478424f, 325.21187564f, 332.47473081f, 339.76289772f, 347.07593991f, 354.41343574f, 361.77497759f, 369.16017124f, 376.56863518f, 384.00000000f, 391.45390785f, 398.93001188f, 406.42797576f, 413.94747321f, 421.48818752f, 429.04981119f, 436.63204548f, 444.23460010f, 451.85719280f, 459.49954906f, 467.16140179f, 474.84249102f, 482.54256363f, 490.26137307f, 497.99867911f, 505.75424759f, 513.52785023f, 521.31926438f, 529.12827280f, 536.95466351f, 544.79822957f, 552.65876890f, 560.53608414f, 568.42998244f, 576.34027536f, 584.26677867f, 592.20931226f, 600.16769996f, 608.14176943f, 616.13135206f, 624.13628279f, 632.15640007f, 640.19154569f, 648.24156472f, 656.30630539f, 664.38561898f, 672.47935976f, 680.58738488f, 688.70955430f, 696.84573069f, 704.99577935f, 713.15956818f, 721.33696754f, 729.52785023f, 737.73209140f, 745.94956849f, 754.18016116f, 762.42375127f, 770.68022275f, 778.94946161f, 787.23135586f, 795.52579543f, 803.83267219f, 812.15187982f, 820.48331383f, 828.82687147f, 837.18245171f, 845.54995518f, 853.92928416f, 862.32034249f, 870.72303558f, 879.13727036f, 887.56295522f, 896.00000000f, 904.44831595f, 912.90781569f, 921.37841320f, 929.86002376f, 938.35256392f, 946.85595152f, 955.37010560f, 963.89494641f, 972.43039537f, 980.97637504f, 989.53280911f, 998.09962237f, 1006.67674069f, 1015.26409097f, 1023.86160116f, 1032.46920021f, 1041.08681805f, 1049.71438560f, 1058.35183469f, 1066.99909811f, 1075.65610955f, 1084.32280357f, 1092.99911564f, 1101.68498204f, 1110.38033993f, 1119.08512727f, 1127.79928282f, 1136.52274614f, 1145.25545758f, 1153.99735821f, 1162.74838989f, 1171.50849518f, 1180.27761738f, 1189.05570047f, 1197.84268914f, 1206.63852876f, 1215.44316535f, 1224.25654560f, 1233.07861684f, 1241.90932703f, 1250.74862473f, 1259.59645914f, 1268.45278005f, 1277.31753781f, 1286.19068338f, 1295.07216828f, 1303.96194457f, 1312.85996488f, 1321.76618236f, 1330.68055071f, 1339.60302413f, 1348.53355734f, 1357.47210556f, 1366.41862452f, 1375.37307041f, 1384.33539991f, 1393.30557020f, 1402.28353887f, 1411.26926400f, 1420.26270412f, 1429.26381818f, 1438.27256558f, 1447.28890615f, 1456.31280014f, 1465.34420819f, 1474.38309138f, 1483.42941118f, 1492.48312945f, 1501.54420843f, 1510.61261078f, 1519.68829949f, 1528.77123795f, 1537.86138993f, 1546.95871952f, 1556.06319119f, 1565.17476976f, 1574.29342040f, 1583.41910860f, 1592.55180020f, 1601.69146137f, 1610.83805860f, 1619.99155871f, 1629.15192882f, 1638.31913637f, 1647.49314911f, 1656.67393509f, 1665.86146266f, 1675.05570047f, 1684.25661744f, 1693.46418280f, 1702.67836605f, 1711.89913698f, 1721.12646563f, 1730.36032233f, 1739.60067768f, 1748.84750254f, 1758.10076802f, 1767.36044551f, 1776.62650662f, 1785.89892323f, 1795.17766747f, 1804.46271172f, 1813.75402857f, 1823.05159087f, 1832.35537170f, 1841.66534438f, 1850.98148244f, 1860.30375965f, 1869.63214999f, 1878.96662767f, 1888.30716711f, 1897.65374295f, 1907.00633003f, 1916.36490342f, 1925.72943838f, 1935.09991037f, 1944.47629506f, 1953.85856831f, 1963.24670620f, 1972.64068498f, 1982.04048108f, 1991.44607117f, 2000.85743204f, 2010.27454072f, 2019.69737440f, 2029.12591044f, 2038.56012640f }; const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX] = { { 0, 0}, { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 1}, { 4, 1}, { 5, 1}, { 5, 1}, { 6, 2}, { 6, 2}, { 6, 2}, { 6, 2}, { 7, 2}, { 7, 2}, { 7, 2}, { 7, 2}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, }; const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126 }; float VP8LFastSLog2Slow(int v) { assert(v >= LOG_LOOKUP_IDX_MAX); if (v < APPROX_LOG_MAX) { int log_cnt = 0; const float v_f = (float)v; while (v >= LOG_LOOKUP_IDX_MAX) { ++log_cnt; v = v >> 1; } return v_f * (kLog2Table[v] + log_cnt); } else { return (float)(LOG_2_RECIPROCAL * v * log((double)v)); } } float VP8LFastLog2Slow(int v) { assert(v >= LOG_LOOKUP_IDX_MAX); if (v < APPROX_LOG_MAX) { int log_cnt = 0; while (v >= LOG_LOOKUP_IDX_MAX) { ++log_cnt; v = v >> 1; } return kLog2Table[v] + log_cnt; } else { return (float)(LOG_2_RECIPROCAL * log((double)v)); } } //------------------------------------------------------------------------------ // Image transforms. // In-place sum of each component with mod 256. static WEBP_INLINE void AddPixelsEq(uint32_t* a, uint32_t b) { const uint32_t alpha_and_green = (*a & 0xff00ff00u) + (b & 0xff00ff00u); const uint32_t red_and_blue = (*a & 0x00ff00ffu) + (b & 0x00ff00ffu); *a = (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu); } static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) { return (((a0 ^ a1) & 0xfefefefeL) >> 1) + (a0 & a1); } static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) { return Average2(Average2(a0, a2), a1); } static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3) { return Average2(Average2(a0, a1), Average2(a2, a3)); } static WEBP_INLINE uint32_t Clip255(uint32_t a) { if (a < 256) { return a; } // return 0, when a is a negative integer. // return 255, when a is positive. return ~a >> 24; } static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) { return Clip255(a + b - c); } static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1, uint32_t c2) { const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24); const int r = AddSubtractComponentFull((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, (c2 >> 16) & 0xff); const int g = AddSubtractComponentFull((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, (c2 >> 8) & 0xff); const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff); return (a << 24) | (r << 16) | (g << 8) | b; } static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) { return Clip255(a + (a - b) / 2); } static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1, uint32_t c2) { const uint32_t ave = Average2(c0, c1); const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24); const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff); const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff); const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff); return (a << 24) | (r << 16) | (g << 8) | b; } static WEBP_INLINE int Sub3(int a, int b, int c) { const int pb = b - c; const int pa = a - c; return abs(pb) - abs(pa); } static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) { const int pa_minus_pb = Sub3((a >> 24) , (b >> 24) , (c >> 24) ) + Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) + Sub3((a >> 8) & 0xff, (b >> 8) & 0xff, (c >> 8) & 0xff) + Sub3((a ) & 0xff, (b ) & 0xff, (c ) & 0xff); return (pa_minus_pb <= 0) ? a : b; } //------------------------------------------------------------------------------ // Predictors static uint32_t Predictor0(uint32_t left, const uint32_t* const top) { (void)top; (void)left; return ARGB_BLACK; } static uint32_t Predictor1(uint32_t left, const uint32_t* const top) { (void)top; return left; } static uint32_t Predictor2(uint32_t left, const uint32_t* const top) { (void)left; return top[0]; } static uint32_t Predictor3(uint32_t left, const uint32_t* const top) { (void)left; return top[1]; } static uint32_t Predictor4(uint32_t left, const uint32_t* const top) { (void)left; return top[-1]; } static uint32_t Predictor5(uint32_t left, const uint32_t* const top) { const uint32_t pred = Average3(left, top[0], top[1]); return pred; } static uint32_t Predictor6(uint32_t left, const uint32_t* const top) { const uint32_t pred = Average2(left, top[-1]); return pred; } static uint32_t Predictor7(uint32_t left, const uint32_t* const top) { const uint32_t pred = Average2(left, top[0]); return pred; } static uint32_t Predictor8(uint32_t left, const uint32_t* const top) { const uint32_t pred = Average2(top[-1], top[0]); (void)left; return pred; } static uint32_t Predictor9(uint32_t left, const uint32_t* const top) { const uint32_t pred = Average2(top[0], top[1]); (void)left; return pred; } static uint32_t Predictor10(uint32_t left, const uint32_t* const top) { const uint32_t pred = Average4(left, top[-1], top[0], top[1]); return pred; } static uint32_t Predictor11(uint32_t left, const uint32_t* const top) { const uint32_t pred = VP8LSelect(top[0], left, top[-1]); return pred; } static uint32_t Predictor12(uint32_t left, const uint32_t* const top) { const uint32_t pred = VP8LClampedAddSubtractFull(left, top[0], top[-1]); return pred; } static uint32_t Predictor13(uint32_t left, const uint32_t* const top) { const uint32_t pred = VP8LClampedAddSubtractHalf(left, top[0], top[-1]); return pred; } // TODO(vikasa): Export the predictor array, to allow SSE2 variants. typedef uint32_t (*PredictorFunc)(uint32_t left, const uint32_t* const top); static const PredictorFunc kPredictors[16] = { Predictor0, Predictor1, Predictor2, Predictor3, Predictor4, Predictor5, Predictor6, Predictor7, Predictor8, Predictor9, Predictor10, Predictor11, Predictor12, Predictor13, Predictor0, Predictor0 // <- padding security sentinels }; // TODO(vikasa): Replace 256 etc with defines. static float PredictionCostSpatial(const int* counts, int weight_0, double exp_val) { const int significant_symbols = 16; const double exp_decay_factor = 0.6; double bits = weight_0 * counts[0]; int i; for (i = 1; i < significant_symbols; ++i) { bits += exp_val * (counts[i] + counts[256 - i]); exp_val *= exp_decay_factor; } return (float)(-0.1 * bits); } // Compute the combined Shanon's entropy for distribution {X} and {X+Y} static float CombinedShannonEntropy(const int* const X, const int* const Y, int n) { int i; double retval = 0.; int sumX = 0, sumXY = 0; for (i = 0; i < n; ++i) { const int x = X[i]; const int xy = X[i] + Y[i]; if (x != 0) { sumX += x; retval -= VP8LFastSLog2(x); } if (xy != 0) { sumXY += xy; retval -= VP8LFastSLog2(xy); } } retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY); return (float)retval; } static float PredictionCostSpatialHistogram(int accumulated[4][256], int tile[4][256]) { int i; double retval = 0; for (i = 0; i < 4; ++i) { const double kExpValue = 0.94; retval += PredictionCostSpatial(tile[i], 1, kExpValue); retval += CombinedShannonEntropy(tile[i], accumulated[i], 256); } return (float)retval; } static int GetBestPredictorForTile(int width, int height, int tile_x, int tile_y, int bits, int accumulated[4][256], const uint32_t* const argb_scratch) { const int kNumPredModes = 14; const int col_start = tile_x << bits; const int row_start = tile_y << bits; const int tile_size = 1 << bits; const int ymax = (tile_size <= height - row_start) ? tile_size : height - row_start; const int xmax = (tile_size <= width - col_start) ? tile_size : width - col_start; int histo[4][256]; float best_diff = MAX_DIFF_COST; int best_mode = 0; int mode; for (mode = 0; mode < kNumPredModes; ++mode) { const uint32_t* current_row = argb_scratch; const PredictorFunc pred_func = kPredictors[mode]; float cur_diff; int y; memset(&histo[0][0], 0, sizeof(histo)); for (y = 0; y < ymax; ++y) { int x; const int row = row_start + y; const uint32_t* const upper_row = current_row; current_row = upper_row + width; for (x = 0; x < xmax; ++x) { const int col = col_start + x; uint32_t predict; uint32_t predict_diff; if (row == 0) { predict = (col == 0) ? ARGB_BLACK : current_row[col - 1]; // Left. } else if (col == 0) { predict = upper_row[col]; // Top. } else { predict = pred_func(current_row[col - 1], upper_row + col); } predict_diff = VP8LSubPixels(current_row[col], predict); ++histo[0][predict_diff >> 24]; ++histo[1][((predict_diff >> 16) & 0xff)]; ++histo[2][((predict_diff >> 8) & 0xff)]; ++histo[3][(predict_diff & 0xff)]; } } cur_diff = PredictionCostSpatialHistogram(accumulated, histo); if (cur_diff < best_diff) { best_diff = cur_diff; best_mode = mode; } } return best_mode; } static void CopyTileWithPrediction(int width, int height, int tile_x, int tile_y, int bits, int mode, const uint32_t* const argb_scratch, uint32_t* const argb) { const int col_start = tile_x << bits; const int row_start = tile_y << bits; const int tile_size = 1 << bits; const int ymax = (tile_size <= height - row_start) ? tile_size : height - row_start; const int xmax = (tile_size <= width - col_start) ? tile_size : width - col_start; const PredictorFunc pred_func = kPredictors[mode]; const uint32_t* current_row = argb_scratch; int y; for (y = 0; y < ymax; ++y) { int x; const int row = row_start + y; const uint32_t* const upper_row = current_row; current_row = upper_row + width; for (x = 0; x < xmax; ++x) { const int col = col_start + x; const int pix = row * width + col; uint32_t predict; if (row == 0) { predict = (col == 0) ? ARGB_BLACK : current_row[col - 1]; // Left. } else if (col == 0) { predict = upper_row[col]; // Top. } else { predict = pred_func(current_row[col - 1], upper_row + col); } argb[pix] = VP8LSubPixels(current_row[col], predict); } } } void VP8LResidualImage(int width, int height, int bits, uint32_t* const argb, uint32_t* const argb_scratch, uint32_t* const image) { const int max_tile_size = 1 << bits; const int tiles_per_row = VP8LSubSampleSize(width, bits); const int tiles_per_col = VP8LSubSampleSize(height, bits); uint32_t* const upper_row = argb_scratch; uint32_t* const current_tile_rows = argb_scratch + width; int tile_y; int histo[4][256]; memset(histo, 0, sizeof(histo)); for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) { const int tile_y_offset = tile_y * max_tile_size; const int this_tile_height = (tile_y < tiles_per_col - 1) ? max_tile_size : height - tile_y_offset; int tile_x; if (tile_y > 0) { memcpy(upper_row, current_tile_rows + (max_tile_size - 1) * width, width * sizeof(*upper_row)); } memcpy(current_tile_rows, &argb[tile_y_offset * width], this_tile_height * width * sizeof(*current_tile_rows)); for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) { int pred; int y; const int tile_x_offset = tile_x * max_tile_size; int all_x_max = tile_x_offset + max_tile_size; if (all_x_max > width) { all_x_max = width; } pred = GetBestPredictorForTile(width, height, tile_x, tile_y, bits, histo, argb_scratch); image[tile_y * tiles_per_row + tile_x] = 0xff000000u | (pred << 8); CopyTileWithPrediction(width, height, tile_x, tile_y, bits, pred, argb_scratch, argb); for (y = 0; y < max_tile_size; ++y) { int ix; int all_x; int all_y = tile_y_offset + y; if (all_y >= height) { break; } ix = all_y * width + tile_x_offset; for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) { const uint32_t a = argb[ix]; ++histo[0][a >> 24]; ++histo[1][((a >> 16) & 0xff)]; ++histo[2][((a >> 8) & 0xff)]; ++histo[3][(a & 0xff)]; } } } } } // Inverse prediction. static void PredictorInverseTransform(const VP8LTransform* const transform, int y_start, int y_end, uint32_t* data) { const int width = transform->xsize_; if (y_start == 0) { // First Row follows the L (mode=1) mode. int x; const uint32_t pred0 = Predictor0(data[-1], NULL); AddPixelsEq(data, pred0); for (x = 1; x < width; ++x) { const uint32_t pred1 = Predictor1(data[x - 1], NULL); AddPixelsEq(data + x, pred1); } data += width; ++y_start; } { int y = y_start; const int mask = (1 << transform->bits_) - 1; const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_); const uint32_t* pred_mode_base = transform->data_ + (y >> transform->bits_) * tiles_per_row; while (y < y_end) { int x; const uint32_t pred2 = Predictor2(data[-1], data - width); const uint32_t* pred_mode_src = pred_mode_base; PredictorFunc pred_func; // First pixel follows the T (mode=2) mode. AddPixelsEq(data, pred2); // .. the rest: pred_func = kPredictors[((*pred_mode_src++) >> 8) & 0xf]; for (x = 1; x < width; ++x) { uint32_t pred; if ((x & mask) == 0) { // start of tile. Read predictor function. pred_func = kPredictors[((*pred_mode_src++) >> 8) & 0xf]; } pred = pred_func(data[x - 1], data + x - width); AddPixelsEq(data + x, pred); } data += width; ++y; if ((y & mask) == 0) { // Use the same mask, since tiles are squares. pred_mode_base += tiles_per_row; } } } } static void SubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixs) { int i = 0; for (; i < num_pixs; ++i) { const uint32_t argb = argb_data[i]; const uint32_t green = (argb >> 8) & 0xff; const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff; const uint32_t new_b = ((argb & 0xff) - green) & 0xff; argb_data[i] = (argb & 0xff00ff00) | (new_r << 16) | new_b; } } // Add green to blue and red channels (i.e. perform the inverse transform of // 'subtract green'). static void AddGreenToBlueAndRed(uint32_t* data, const uint32_t* data_end) { while (data < data_end) { const uint32_t argb = *data; const uint32_t green = ((argb >> 8) & 0xff); uint32_t red_blue = (argb & 0x00ff00ffu); red_blue += (green << 16) | green; red_blue &= 0x00ff00ffu; *data++ = (argb & 0xff00ff00u) | red_blue; } } typedef struct { // Note: the members are uint8_t, so that any negative values are // automatically converted to "mod 256" values. uint8_t green_to_red_; uint8_t green_to_blue_; uint8_t red_to_blue_; } Multipliers; static WEBP_INLINE void MultipliersClear(Multipliers* m) { m->green_to_red_ = 0; m->green_to_blue_ = 0; m->red_to_blue_ = 0; } static WEBP_INLINE uint32_t ColorTransformDelta(int8_t color_pred, int8_t color) { return (uint32_t)((int)(color_pred) * color) >> 5; } static WEBP_INLINE void ColorCodeToMultipliers(uint32_t color_code, Multipliers* const m) { m->green_to_red_ = (color_code >> 0) & 0xff; m->green_to_blue_ = (color_code >> 8) & 0xff; m->red_to_blue_ = (color_code >> 16) & 0xff; } static WEBP_INLINE uint32_t MultipliersToColorCode(Multipliers* const m) { return 0xff000000u | ((uint32_t)(m->red_to_blue_) << 16) | ((uint32_t)(m->green_to_blue_) << 8) | m->green_to_red_; } static WEBP_INLINE uint32_t TransformColor(const Multipliers* const m, uint32_t argb, int inverse) { const uint32_t green = argb >> 8; const uint32_t red = argb >> 16; uint32_t new_red = red; uint32_t new_blue = argb; if (inverse) { new_red += ColorTransformDelta(m->green_to_red_, green); new_red &= 0xff; new_blue += ColorTransformDelta(m->green_to_blue_, green); new_blue += ColorTransformDelta(m->red_to_blue_, new_red); new_blue &= 0xff; } else { new_red -= ColorTransformDelta(m->green_to_red_, green); new_red &= 0xff; new_blue -= ColorTransformDelta(m->green_to_blue_, green); new_blue -= ColorTransformDelta(m->red_to_blue_, red); new_blue &= 0xff; } return (argb & 0xff00ff00u) | (new_red << 16) | (new_blue); } static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red, uint32_t argb) { const uint32_t green = argb >> 8; uint32_t new_red = argb >> 16; new_red -= ColorTransformDelta(green_to_red, green); return (new_red & 0xff); } static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue, uint8_t red_to_blue, uint32_t argb) { const uint32_t green = argb >> 8; const uint32_t red = argb >> 16; uint8_t new_blue = argb; new_blue -= ColorTransformDelta(green_to_blue, green); new_blue -= ColorTransformDelta(red_to_blue, red); return (new_blue & 0xff); } static WEBP_INLINE int SkipRepeatedPixels(const uint32_t* const argb, int ix, int xsize) { const uint32_t v = argb[ix]; if (ix >= xsize + 3) { if (v == argb[ix - xsize] && argb[ix - 1] == argb[ix - xsize - 1] && argb[ix - 2] == argb[ix - xsize - 2] && argb[ix - 3] == argb[ix - xsize - 3]) { return 1; } return v == argb[ix - 3] && v == argb[ix - 2] && v == argb[ix - 1]; } else if (ix >= 3) { return v == argb[ix - 3] && v == argb[ix - 2] && v == argb[ix - 1]; } return 0; } static float PredictionCostCrossColor(const int accumulated[256], const int counts[256]) { // Favor low entropy, locally and globally. // Favor small absolute values for PredictionCostSpatial static const double kExpValue = 2.4; return CombinedShannonEntropy(counts, accumulated, 256) + PredictionCostSpatial(counts, 3, kExpValue); } static Multipliers GetBestColorTransformForTile( int tile_x, int tile_y, int bits, Multipliers prevX, Multipliers prevY, int step, int xsize, int ysize, int* accumulated_red_histo, int* accumulated_blue_histo, const uint32_t* const argb) { float best_diff = MAX_DIFF_COST; float cur_diff; const int halfstep = step / 2; const int max_tile_size = 1 << bits; const int tile_y_offset = tile_y * max_tile_size; const int tile_x_offset = tile_x * max_tile_size; int green_to_red; int green_to_blue; int red_to_blue; int all_x_max = tile_x_offset + max_tile_size; int all_y_max = tile_y_offset + max_tile_size; Multipliers best_tx; MultipliersClear(&best_tx); if (all_x_max > xsize) { all_x_max = xsize; } if (all_y_max > ysize) { all_y_max = ysize; } for (green_to_red = -64; green_to_red <= 64; green_to_red += halfstep) { int histo[256] = { 0 }; int all_y; for (all_y = tile_y_offset; all_y < all_y_max; ++all_y) { int ix = all_y * xsize + tile_x_offset; int all_x; for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) { if (SkipRepeatedPixels(argb, ix, xsize)) { continue; } ++histo[TransformColorRed(green_to_red, argb[ix])]; // red. } } cur_diff = PredictionCostCrossColor(&accumulated_red_histo[0], &histo[0]); if ((uint8_t)green_to_red == prevX.green_to_red_) { cur_diff -= 3; // favor keeping the areas locally similar } if ((uint8_t)green_to_red == prevY.green_to_red_) { cur_diff -= 3; // favor keeping the areas locally similar } if (green_to_red == 0) { cur_diff -= 3; } if (cur_diff < best_diff) { best_diff = cur_diff; best_tx.green_to_red_ = green_to_red; } } best_diff = MAX_DIFF_COST; for (green_to_blue = -32; green_to_blue <= 32; green_to_blue += step) { for (red_to_blue = -32; red_to_blue <= 32; red_to_blue += step) { int all_y; int histo[256] = { 0 }; for (all_y = tile_y_offset; all_y < all_y_max; ++all_y) { int all_x; int ix = all_y * xsize + tile_x_offset; for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) { if (SkipRepeatedPixels(argb, ix, xsize)) { continue; } ++histo[TransformColorBlue(green_to_blue, red_to_blue, argb[ix])]; } } cur_diff = PredictionCostCrossColor(&accumulated_blue_histo[0], &histo[0]); if ((uint8_t)green_to_blue == prevX.green_to_blue_) { cur_diff -= 3; // favor keeping the areas locally similar } if ((uint8_t)green_to_blue == prevY.green_to_blue_) { cur_diff -= 3; // favor keeping the areas locally similar } if ((uint8_t)red_to_blue == prevX.red_to_blue_) { cur_diff -= 3; // favor keeping the areas locally similar } if ((uint8_t)red_to_blue == prevY.red_to_blue_) { cur_diff -= 3; // favor keeping the areas locally similar } if (green_to_blue == 0) { cur_diff -= 3; } if (red_to_blue == 0) { cur_diff -= 3; } if (cur_diff < best_diff) { best_diff = cur_diff; best_tx.green_to_blue_ = green_to_blue; best_tx.red_to_blue_ = red_to_blue; } } } return best_tx; } static void CopyTileWithColorTransform(int xsize, int ysize, int tile_x, int tile_y, int bits, Multipliers color_transform, uint32_t* const argb) { int y; int xscan = 1 << bits; int yscan = 1 << bits; tile_x <<= bits; tile_y <<= bits; if (xscan > xsize - tile_x) { xscan = xsize - tile_x; } if (yscan > ysize - tile_y) { yscan = ysize - tile_y; } yscan += tile_y; for (y = tile_y; y < yscan; ++y) { int ix = y * xsize + tile_x; const int end_ix = ix + xscan; for (; ix < end_ix; ++ix) { argb[ix] = TransformColor(&color_transform, argb[ix], 0); } } } void VP8LColorSpaceTransform(int width, int height, int bits, int step, uint32_t* const argb, uint32_t* image) { const int max_tile_size = 1 << bits; int tile_xsize = VP8LSubSampleSize(width, bits); int tile_ysize = VP8LSubSampleSize(height, bits); int accumulated_red_histo[256] = { 0 }; int accumulated_blue_histo[256] = { 0 }; int tile_y; int tile_x; Multipliers prevX; Multipliers prevY; MultipliersClear(&prevY); MultipliersClear(&prevX); for (tile_y = 0; tile_y < tile_ysize; ++tile_y) { for (tile_x = 0; tile_x < tile_xsize; ++tile_x) { Multipliers color_transform; int all_x_max; int y; const int tile_y_offset = tile_y * max_tile_size; const int tile_x_offset = tile_x * max_tile_size; if (tile_y != 0) { ColorCodeToMultipliers(image[tile_y * tile_xsize + tile_x - 1], &prevX); ColorCodeToMultipliers(image[(tile_y - 1) * tile_xsize + tile_x], &prevY); } else if (tile_x != 0) { ColorCodeToMultipliers(image[tile_y * tile_xsize + tile_x - 1], &prevX); } color_transform = GetBestColorTransformForTile(tile_x, tile_y, bits, prevX, prevY, step, width, height, &accumulated_red_histo[0], &accumulated_blue_histo[0], argb); image[tile_y * tile_xsize + tile_x] = MultipliersToColorCode(&color_transform); CopyTileWithColorTransform(width, height, tile_x, tile_y, bits, color_transform, argb); // Gather accumulated histogram data. all_x_max = tile_x_offset + max_tile_size; if (all_x_max > width) { all_x_max = width; } for (y = 0; y < max_tile_size; ++y) { int ix; int all_x; int all_y = tile_y_offset + y; if (all_y >= height) { break; } ix = all_y * width + tile_x_offset; for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) { if (ix >= 2 && argb[ix] == argb[ix - 2] && argb[ix] == argb[ix - 1]) { continue; // repeated pixels are handled by backward references } if (ix >= width + 2 && argb[ix - 2] == argb[ix - width - 2] && argb[ix - 1] == argb[ix - width - 1] && argb[ix] == argb[ix - width]) { continue; // repeated pixels are handled by backward references } ++accumulated_red_histo[(argb[ix] >> 16) & 0xff]; ++accumulated_blue_histo[argb[ix] & 0xff]; } } } } } // Color space inverse transform. static void ColorSpaceInverseTransform(const VP8LTransform* const transform, int y_start, int y_end, uint32_t* data) { const int width = transform->xsize_; const int mask = (1 << transform->bits_) - 1; const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_); int y = y_start; const uint32_t* pred_row = transform->data_ + (y >> transform->bits_) * tiles_per_row; while (y < y_end) { const uint32_t* pred = pred_row; Multipliers m = { 0, 0, 0 }; int x; for (x = 0; x < width; ++x) { if ((x & mask) == 0) ColorCodeToMultipliers(*pred++, &m); data[x] = TransformColor(&m, data[x], 1); } data += width; ++y; if ((y & mask) == 0) pred_row += tiles_per_row;; } } // Separate out pixels packed together using pixel-bundling. // We define two methods for ARGB data (uint32_t) and alpha-only data (uint8_t). #define COLOR_INDEX_INVERSE(FUNC_NAME, TYPE, GET_INDEX, GET_VALUE) \ void FUNC_NAME(const VP8LTransform* const transform, \ int y_start, int y_end, const TYPE* src, TYPE* dst) { \ int y; \ const int bits_per_pixel = 8 >> transform->bits_; \ const int width = transform->xsize_; \ const uint32_t* const color_map = transform->data_; \ if (bits_per_pixel < 8) { \ const int pixels_per_byte = 1 << transform->bits_; \ const int count_mask = pixels_per_byte - 1; \ const uint32_t bit_mask = (1 << bits_per_pixel) - 1; \ for (y = y_start; y < y_end; ++y) { \ uint32_t packed_pixels = 0; \ int x; \ for (x = 0; x < width; ++x) { \ /* We need to load fresh 'packed_pixels' once every */ \ /* 'pixels_per_byte' increments of x. Fortunately, pixels_per_byte */ \ /* is a power of 2, so can just use a mask for that, instead of */ \ /* decrementing a counter. */ \ if ((x & count_mask) == 0) packed_pixels = GET_INDEX(*src++); \ *dst++ = GET_VALUE(color_map[packed_pixels & bit_mask]); \ packed_pixels >>= bits_per_pixel; \ } \ } \ } else { \ for (y = y_start; y < y_end; ++y) { \ int x; \ for (x = 0; x < width; ++x) { \ *dst++ = GET_VALUE(color_map[GET_INDEX(*src++)]); \ } \ } \ } \ } static WEBP_INLINE uint32_t GetARGBIndex(uint32_t idx) { return (idx >> 8) & 0xff; } static WEBP_INLINE uint8_t GetAlphaIndex(uint8_t idx) { return idx; } static WEBP_INLINE uint32_t GetARGBValue(uint32_t val) { return val; } static WEBP_INLINE uint8_t GetAlphaValue(uint32_t val) { return (val >> 8) & 0xff; } static COLOR_INDEX_INVERSE(ColorIndexInverseTransform, uint32_t, GetARGBIndex, GetARGBValue) COLOR_INDEX_INVERSE(VP8LColorIndexInverseTransformAlpha, uint8_t, GetAlphaIndex, GetAlphaValue) #undef COLOR_INDEX_INVERSE void VP8LInverseTransform(const VP8LTransform* const transform, int row_start, int row_end, const uint32_t* const in, uint32_t* const out) { const int width = transform->xsize_; assert(row_start < row_end); assert(row_end <= transform->ysize_); switch (transform->type_) { case SUBTRACT_GREEN: VP8LAddGreenToBlueAndRed(out, out + (row_end - row_start) * width); break; case PREDICTOR_TRANSFORM: PredictorInverseTransform(transform, row_start, row_end, out); if (row_end != transform->ysize_) { // The last predicted row in this iteration will be the top-pred row // for the first row in next iteration. memcpy(out - width, out + (row_end - row_start - 1) * width, width * sizeof(*out)); } break; case CROSS_COLOR_TRANSFORM: ColorSpaceInverseTransform(transform, row_start, row_end, out); break; case COLOR_INDEXING_TRANSFORM: if (in == out && transform->bits_ > 0) { // Move packed pixels to the end of unpacked region, so that unpacking // can occur seamlessly. // Also, note that this is the only transform that applies on // the effective width of VP8LSubSampleSize(xsize_, bits_). All other // transforms work on effective width of xsize_. const int out_stride = (row_end - row_start) * width; const int in_stride = (row_end - row_start) * VP8LSubSampleSize(transform->xsize_, transform->bits_); uint32_t* const src = out + out_stride - in_stride; memmove(src, out, in_stride * sizeof(*src)); ColorIndexInverseTransform(transform, row_start, row_end, src, out); } else { ColorIndexInverseTransform(transform, row_start, row_end, in, out); } break; } } //------------------------------------------------------------------------------ // Color space conversion. static int is_big_endian(void) { static const union { uint16_t w; uint8_t b[2]; } tmp = { 1 }; return (tmp.b[0] != 1); } static void ConvertBGRAToRGB(const uint32_t* src, int num_pixels, uint8_t* dst) { const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; *dst++ = (argb >> 16) & 0xff; *dst++ = (argb >> 8) & 0xff; *dst++ = (argb >> 0) & 0xff; } } static void ConvertBGRAToRGBA(const uint32_t* src, int num_pixels, uint8_t* dst) { const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; *dst++ = (argb >> 16) & 0xff; *dst++ = (argb >> 8) & 0xff; *dst++ = (argb >> 0) & 0xff; *dst++ = (argb >> 24) & 0xff; } } static void ConvertBGRAToRGBA4444(const uint32_t* src, int num_pixels, uint8_t* dst) { const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; const uint8_t rg = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf); const uint8_t ba = ((argb >> 0) & 0xf0) | ((argb >> 28) & 0xf); #ifdef WEBP_SWAP_16BIT_CSP *dst++ = ba; *dst++ = rg; #else *dst++ = rg; *dst++ = ba; #endif } } static void ConvertBGRAToRGB565(const uint32_t* src, int num_pixels, uint8_t* dst) { const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; const uint8_t rg = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7); const uint8_t gb = ((argb >> 5) & 0xe0) | ((argb >> 3) & 0x1f); #ifdef WEBP_SWAP_16BIT_CSP *dst++ = gb; *dst++ = rg; #else *dst++ = rg; *dst++ = gb; #endif } } static void ConvertBGRAToBGR(const uint32_t* src, int num_pixels, uint8_t* dst) { const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; *dst++ = (argb >> 0) & 0xff; *dst++ = (argb >> 8) & 0xff; *dst++ = (argb >> 16) & 0xff; } } static void CopyOrSwap(const uint32_t* src, int num_pixels, uint8_t* dst, int swap_on_big_endian) { if (is_big_endian() == swap_on_big_endian) { const uint32_t* const src_end = src + num_pixels; while (src < src_end) { uint32_t argb = *src++; #if !defined(__BIG_ENDIAN__) #if !defined(WEBP_REFERENCE_IMPLEMENTATION) #if defined(__i386__) || defined(__x86_64__) __asm__ volatile("bswap %0" : "=r"(argb) : "0"(argb)); *(uint32_t*)dst = argb; #elif defined(_MSC_VER) argb = _byteswap_ulong(argb); *(uint32_t*)dst = argb; #else dst[0] = (argb >> 24) & 0xff; dst[1] = (argb >> 16) & 0xff; dst[2] = (argb >> 8) & 0xff; dst[3] = (argb >> 0) & 0xff; #endif #else // WEBP_REFERENCE_IMPLEMENTATION dst[0] = (argb >> 24) & 0xff; dst[1] = (argb >> 16) & 0xff; dst[2] = (argb >> 8) & 0xff; dst[3] = (argb >> 0) & 0xff; #endif #else // __BIG_ENDIAN__ dst[0] = (argb >> 0) & 0xff; dst[1] = (argb >> 8) & 0xff; dst[2] = (argb >> 16) & 0xff; dst[3] = (argb >> 24) & 0xff; #endif dst += sizeof(argb); } } else { memcpy(dst, src, num_pixels * sizeof(*src)); } } void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels, WEBP_CSP_MODE out_colorspace, uint8_t* const rgba) { switch (out_colorspace) { case MODE_RGB: ConvertBGRAToRGB(in_data, num_pixels, rgba); break; case MODE_RGBA: ConvertBGRAToRGBA(in_data, num_pixels, rgba); break; case MODE_rgbA: ConvertBGRAToRGBA(in_data, num_pixels, rgba); WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0); break; case MODE_BGR: ConvertBGRAToBGR(in_data, num_pixels, rgba); break; case MODE_BGRA: CopyOrSwap(in_data, num_pixels, rgba, 1); break; case MODE_bgrA: CopyOrSwap(in_data, num_pixels, rgba, 1); WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0); break; case MODE_ARGB: CopyOrSwap(in_data, num_pixels, rgba, 0); break; case MODE_Argb: CopyOrSwap(in_data, num_pixels, rgba, 0); WebPApplyAlphaMultiply(rgba, 1, num_pixels, 1, 0); break; case MODE_RGBA_4444: ConvertBGRAToRGBA4444(in_data, num_pixels, rgba); break; case MODE_rgbA_4444: ConvertBGRAToRGBA4444(in_data, num_pixels, rgba); WebPApplyAlphaMultiply4444(rgba, num_pixels, 1, 0); break; case MODE_RGB_565: ConvertBGRAToRGB565(in_data, num_pixels, rgba); break; default: assert(0); // Code flow should not reach here. } } // Bundles multiple (1, 2, 4 or 8) pixels into a single pixel. void VP8LBundleColorMap(const uint8_t* const row, int width, int xbits, uint32_t* const dst) { int x; if (xbits > 0) { const int bit_depth = 1 << (3 - xbits); const int mask = (1 << xbits) - 1; uint32_t code = 0xff000000; for (x = 0; x < width; ++x) { const int xsub = x & mask; if (xsub == 0) { code = 0xff000000; } code |= row[x] << (8 + bit_depth * xsub); dst[x >> xbits] = code; } } else { for (x = 0; x < width; ++x) dst[x] = 0xff000000 | (row[x] << 8); } } //------------------------------------------------------------------------------ // TODO(vikasa): Move the SSE2 functions to lossless_dsp.c (new file), once // color-space conversion methods (ConvertFromBGRA) are also updated for SSE2. #if defined(WEBP_USE_SSE2) static WEBP_INLINE uint32_t ClampedAddSubtractFullSSE2(uint32_t c0, uint32_t c1, uint32_t c2) { const __m128i zero = _mm_setzero_si128(); const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero); const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero); const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero); const __m128i V1 = _mm_add_epi16(C0, C1); const __m128i V2 = _mm_sub_epi16(V1, C2); const __m128i b = _mm_packus_epi16(V2, V2); const uint32_t output = _mm_cvtsi128_si32(b); return output; } static WEBP_INLINE uint32_t ClampedAddSubtractHalfSSE2(uint32_t c0, uint32_t c1, uint32_t c2) { const uint32_t ave = Average2(c0, c1); const __m128i zero = _mm_setzero_si128(); const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(ave), zero); const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero); const __m128i A1 = _mm_sub_epi16(A0, B0); const __m128i BgtA = _mm_cmpgt_epi16(B0, A0); const __m128i A2 = _mm_sub_epi16(A1, BgtA); const __m128i A3 = _mm_srai_epi16(A2, 1); const __m128i A4 = _mm_add_epi16(A0, A3); const __m128i A5 = _mm_packus_epi16(A4, A4); const uint32_t output = _mm_cvtsi128_si32(A5); return output; } static WEBP_INLINE uint32_t SelectSSE2(uint32_t a, uint32_t b, uint32_t c) { int pa_minus_pb; const __m128i zero = _mm_setzero_si128(); const __m128i A0 = _mm_cvtsi32_si128(a); const __m128i B0 = _mm_cvtsi32_si128(b); const __m128i C0 = _mm_cvtsi32_si128(c); const __m128i AC0 = _mm_subs_epu8(A0, C0); const __m128i CA0 = _mm_subs_epu8(C0, A0); const __m128i BC0 = _mm_subs_epu8(B0, C0); const __m128i CB0 = _mm_subs_epu8(C0, B0); const __m128i AC = _mm_or_si128(AC0, CA0); const __m128i BC = _mm_or_si128(BC0, CB0); const __m128i pa = _mm_unpacklo_epi8(AC, zero); // |a - c| const __m128i pb = _mm_unpacklo_epi8(BC, zero); // |b - c| const __m128i diff = _mm_sub_epi16(pb, pa); { int16_t out[8]; _mm_storeu_si128((__m128i*)out, diff); pa_minus_pb = out[0] + out[1] + out[2] + out[3]; } return (pa_minus_pb <= 0) ? a : b; } static void SubtractGreenFromBlueAndRedSSE2(uint32_t* argb_data, int num_pixs) { int i = 0; const __m128i mask = _mm_set1_epi32(0x0000ff00); for (; i + 4 < num_pixs; i += 4) { const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]); const __m128i in_00g0 = _mm_and_si128(in, mask); // 00g0|00g0|... const __m128i in_0g00 = _mm_slli_epi32(in_00g0, 8); // 0g00|0g00|... const __m128i in_000g = _mm_srli_epi32(in_00g0, 8); // 000g|000g|... const __m128i in_0g0g = _mm_or_si128(in_0g00, in_000g); const __m128i out = _mm_sub_epi8(in, in_0g0g); _mm_storeu_si128((__m128i*)&argb_data[i], out); } // fallthrough and finish off with plain-C for (; i < num_pixs; ++i) { const uint32_t argb = argb_data[i]; const uint32_t green = (argb >> 8) & 0xff; const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff; const uint32_t new_b = ((argb & 0xff) - green) & 0xff; argb_data[i] = (argb & 0xff00ff00) | (new_r << 16) | new_b; } } static void AddGreenToBlueAndRedSSE2(uint32_t* data, const uint32_t* data_end) { const __m128i mask = _mm_set1_epi32(0x0000ff00); for (; data + 4 < data_end; data += 4) { const __m128i in = _mm_loadu_si128((__m128i*)data); const __m128i in_00g0 = _mm_and_si128(in, mask); // 00g0|00g0|... const __m128i in_0g00 = _mm_slli_epi32(in_00g0, 8); // 0g00|0g00|... const __m128i in_000g = _mm_srli_epi32(in_00g0, 8); // 000g|000g|... const __m128i in_0g0g = _mm_or_si128(in_0g00, in_000g); const __m128i out = _mm_add_epi8(in, in_0g0g); _mm_storeu_si128((__m128i*)data, out); } // fallthrough and finish off with plain-C while (data < data_end) { const uint32_t argb = *data; const uint32_t green = ((argb >> 8) & 0xff); uint32_t red_blue = (argb & 0x00ff00ffu); red_blue += (green << 16) | green; red_blue &= 0x00ff00ffu; *data++ = (argb & 0xff00ff00u) | red_blue; } } extern void VP8LDspInitSSE2(void); void VP8LDspInitSSE2(void) { VP8LClampedAddSubtractFull = ClampedAddSubtractFullSSE2; VP8LClampedAddSubtractHalf = ClampedAddSubtractHalfSSE2; VP8LSelect = SelectSSE2; VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRedSSE2; VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRedSSE2; } #endif //------------------------------------------------------------------------------ VP8LPredClampedAddSubFunc VP8LClampedAddSubtractFull; VP8LPredClampedAddSubFunc VP8LClampedAddSubtractHalf; VP8LPredSelectFunc VP8LSelect; VP8LSubtractGreenFromBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed; VP8LAddGreenToBlueAndRedFunc VP8LAddGreenToBlueAndRed; void VP8LDspInit(void) { VP8LClampedAddSubtractFull = ClampedAddSubtractFull; VP8LClampedAddSubtractHalf = ClampedAddSubtractHalf; VP8LSelect = Select; VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRed; VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed; // If defined, use CPUInfo() to overwrite some pointers with faster versions. if (VP8GetCPUInfo != NULL) { #if defined(WEBP_USE_SSE2) if (VP8GetCPUInfo(kSSE2)) { VP8LDspInitSSE2(); } #endif } } //------------------------------------------------------------------------------ libwebp-0.4.0/src/dsp/upsampling.c0000644000014400001440000004034712255002107013751 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // YUV to RGB upsampling functions. // // Author: somnath@google.com (Somnath Banerjee) #include "./dsp.h" #include "./yuv.h" #include //------------------------------------------------------------------------------ // Fancy upsampler #ifdef FANCY_UPSAMPLING // Fancy upsampling functions to convert YUV to RGB WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST]; // Given samples laid out in a square as: // [a b] // [c d] // we interpolate u/v as: // ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16 // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 // We process u and v together stashed into 32bit (16bit each). #define LOAD_UV(u, v) ((u) | ((v) << 16)) #define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ const uint8_t* top_u, const uint8_t* top_v, \ const uint8_t* cur_u, const uint8_t* cur_v, \ uint8_t* top_dst, uint8_t* bottom_dst, int len) { \ int x; \ const int last_pixel_pair = (len - 1) >> 1; \ uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]); /* top-left sample */ \ uint32_t l_uv = LOAD_UV(cur_u[0], cur_v[0]); /* left-sample */ \ assert(top_y != NULL); \ { \ const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst); \ } \ if (bottom_y != NULL) { \ const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst); \ } \ for (x = 1; x <= last_pixel_pair; ++x) { \ const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]); /* top sample */ \ const uint32_t uv = LOAD_UV(cur_u[x], cur_v[x]); /* sample */ \ /* precompute invariant values associated with first and second diagonals*/\ const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u; \ const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3; \ const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3; \ { \ const uint32_t uv0 = (diag_12 + tl_uv) >> 1; \ const uint32_t uv1 = (diag_03 + t_uv) >> 1; \ FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ top_dst + (2 * x - 1) * XSTEP); \ FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16), \ top_dst + (2 * x - 0) * XSTEP); \ } \ if (bottom_y != NULL) { \ const uint32_t uv0 = (diag_03 + l_uv) >> 1; \ const uint32_t uv1 = (diag_12 + uv) >> 1; \ FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ bottom_dst + (2 * x - 1) * XSTEP); \ FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16), \ bottom_dst + (2 * x + 0) * XSTEP); \ } \ tl_uv = t_uv; \ l_uv = uv; \ } \ if (!(len & 1)) { \ { \ const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ top_dst + (len - 1) * XSTEP); \ } \ if (bottom_y != NULL) { \ const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ bottom_dst + (len - 1) * XSTEP); \ } \ } \ } // All variants implemented. UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3) UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3) UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4) UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4) UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4) UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2) UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2) #undef LOAD_UV #undef UPSAMPLE_FUNC #endif // FANCY_UPSAMPLING //------------------------------------------------------------------------------ // simple point-sampling #define SAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ const uint8_t* u, const uint8_t* v, \ uint8_t* top_dst, uint8_t* bottom_dst, int len) { \ int i; \ for (i = 0; i < len - 1; i += 2) { \ FUNC(top_y[0], u[0], v[0], top_dst); \ FUNC(top_y[1], u[0], v[0], top_dst + XSTEP); \ FUNC(bottom_y[0], u[0], v[0], bottom_dst); \ FUNC(bottom_y[1], u[0], v[0], bottom_dst + XSTEP); \ top_y += 2; \ bottom_y += 2; \ u++; \ v++; \ top_dst += 2 * XSTEP; \ bottom_dst += 2 * XSTEP; \ } \ if (i == len - 1) { /* last one */ \ FUNC(top_y[0], u[0], v[0], top_dst); \ FUNC(bottom_y[0], u[0], v[0], bottom_dst); \ } \ } // All variants implemented. SAMPLE_FUNC(SampleRgbLinePair, VP8YuvToRgb, 3) SAMPLE_FUNC(SampleBgrLinePair, VP8YuvToBgr, 3) SAMPLE_FUNC(SampleRgbaLinePair, VP8YuvToRgba, 4) SAMPLE_FUNC(SampleBgraLinePair, VP8YuvToBgra, 4) SAMPLE_FUNC(SampleArgbLinePair, VP8YuvToArgb, 4) SAMPLE_FUNC(SampleRgba4444LinePair, VP8YuvToRgba4444, 2) SAMPLE_FUNC(SampleRgb565LinePair, VP8YuvToRgb565, 2) #undef SAMPLE_FUNC const WebPSampleLinePairFunc WebPSamplers[MODE_LAST] = { SampleRgbLinePair, // MODE_RGB SampleRgbaLinePair, // MODE_RGBA SampleBgrLinePair, // MODE_BGR SampleBgraLinePair, // MODE_BGRA SampleArgbLinePair, // MODE_ARGB SampleRgba4444LinePair, // MODE_RGBA_4444 SampleRgb565LinePair, // MODE_RGB_565 SampleRgbaLinePair, // MODE_rgbA SampleBgraLinePair, // MODE_bgrA SampleArgbLinePair, // MODE_Argb SampleRgba4444LinePair // MODE_rgbA_4444 }; //------------------------------------------------------------------------------ #if !defined(FANCY_UPSAMPLING) #define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC) \ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \ const uint8_t* top_u, const uint8_t* top_v, \ const uint8_t* bot_u, const uint8_t* bot_v, \ uint8_t* top_dst, uint8_t* bot_dst, int len) { \ const int half_len = len >> 1; \ int x; \ assert(top_dst != NULL); \ { \ for (x = 0; x < half_len; ++x) { \ FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0); \ FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4); \ } \ if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x); \ } \ if (bot_dst != NULL) { \ for (x = 0; x < half_len; ++x) { \ FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0); \ FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4); \ } \ if (len & 1) FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x); \ } \ } DUAL_SAMPLE_FUNC(DualLineSamplerBGRA, VP8YuvToBgra) DUAL_SAMPLE_FUNC(DualLineSamplerARGB, VP8YuvToArgb) #undef DUAL_SAMPLE_FUNC #endif // !FANCY_UPSAMPLING WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last) { WebPInitUpsamplers(); VP8YUVInit(); #ifdef FANCY_UPSAMPLING return WebPUpsamplers[alpha_is_last ? MODE_BGRA : MODE_ARGB]; #else return (alpha_is_last ? DualLineSamplerBGRA : DualLineSamplerARGB); #endif } //------------------------------------------------------------------------------ // YUV444 converter #define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP) \ static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v, \ uint8_t* dst, int len) { \ int i; \ for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]); \ } YUV444_FUNC(Yuv444ToRgb, VP8YuvToRgb, 3) YUV444_FUNC(Yuv444ToBgr, VP8YuvToBgr, 3) YUV444_FUNC(Yuv444ToRgba, VP8YuvToRgba, 4) YUV444_FUNC(Yuv444ToBgra, VP8YuvToBgra, 4) YUV444_FUNC(Yuv444ToArgb, VP8YuvToArgb, 4) YUV444_FUNC(Yuv444ToRgba4444, VP8YuvToRgba4444, 2) YUV444_FUNC(Yuv444ToRgb565, VP8YuvToRgb565, 2) #undef YUV444_FUNC const WebPYUV444Converter WebPYUV444Converters[MODE_LAST] = { Yuv444ToRgb, // MODE_RGB Yuv444ToRgba, // MODE_RGBA Yuv444ToBgr, // MODE_BGR Yuv444ToBgra, // MODE_BGRA Yuv444ToArgb, // MODE_ARGB Yuv444ToRgba4444, // MODE_RGBA_4444 Yuv444ToRgb565, // MODE_RGB_565 Yuv444ToRgba, // MODE_rgbA Yuv444ToBgra, // MODE_bgrA Yuv444ToArgb, // MODE_Argb Yuv444ToRgba4444 // MODE_rgbA_4444 }; //------------------------------------------------------------------------------ // Premultiplied modes // non dithered-modes // (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.) // for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5), // one can use instead: (x * a * 65793 + (1 << 23)) >> 24 #if 1 // (int)(x * a / 255.) #define MULTIPLIER(a) ((a) * 32897UL) #define PREMULTIPLY(x, m) (((x) * (m)) >> 23) #else // (int)(x * a / 255. + .5) #define MULTIPLIER(a) ((a) * 65793UL) #define PREMULTIPLY(x, m) (((x) * (m) + (1UL << 23)) >> 24) #endif static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first, int w, int h, int stride) { while (h-- > 0) { uint8_t* const rgb = rgba + (alpha_first ? 1 : 0); const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3); int i; for (i = 0; i < w; ++i) { const uint32_t a = alpha[4 * i]; if (a != 0xff) { const uint32_t mult = MULTIPLIER(a); rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult); rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult); rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult); } } rgba += stride; } } #undef MULTIPLIER #undef PREMULTIPLY // rgbA4444 #define MULTIPLIER(a) ((a) * 0x1111) // 0x1111 ~= (1 << 16) / 15 static WEBP_INLINE uint8_t dither_hi(uint8_t x) { return (x & 0xf0) | (x >> 4); } static WEBP_INLINE uint8_t dither_lo(uint8_t x) { return (x & 0x0f) | (x << 4); } static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) { return (x * m) >> 16; } static void ApplyAlphaMultiply4444(uint8_t* rgba4444, int w, int h, int stride) { while (h-- > 0) { int i; for (i = 0; i < w; ++i) { const uint8_t a = (rgba4444[2 * i + 1] & 0x0f); const uint32_t mult = MULTIPLIER(a); const uint8_t r = multiply(dither_hi(rgba4444[2 * i + 0]), mult); const uint8_t g = multiply(dither_lo(rgba4444[2 * i + 0]), mult); const uint8_t b = multiply(dither_hi(rgba4444[2 * i + 1]), mult); rgba4444[2 * i + 0] = (r & 0xf0) | ((g >> 4) & 0x0f); rgba4444[2 * i + 1] = (b & 0xf0) | a; } rgba4444 += stride; } } #undef MULTIPLIER void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int) = ApplyAlphaMultiply; void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int) = ApplyAlphaMultiply4444; //------------------------------------------------------------------------------ // Main call void WebPInitUpsamplers(void) { #ifdef FANCY_UPSAMPLING WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair; WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair; WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair; WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair; WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair; WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair; WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair; // If defined, use CPUInfo() to overwrite some pointers with faster versions. if (VP8GetCPUInfo != NULL) { #if defined(WEBP_USE_SSE2) if (VP8GetCPUInfo(kSSE2)) { WebPInitUpsamplersSSE2(); } #endif #if defined(WEBP_USE_NEON) if (VP8GetCPUInfo(kNEON)) { WebPInitUpsamplersNEON(); } #endif } #endif // FANCY_UPSAMPLING } void WebPInitPremultiply(void) { WebPApplyAlphaMultiply = ApplyAlphaMultiply; WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply4444; #ifdef FANCY_UPSAMPLING WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair; WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair; WebPUpsamplers[MODE_Argb] = UpsampleArgbLinePair; WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair; if (VP8GetCPUInfo != NULL) { #if defined(WEBP_USE_SSE2) if (VP8GetCPUInfo(kSSE2)) { WebPInitPremultiplySSE2(); } #endif #if defined(WEBP_USE_NEON) if (VP8GetCPUInfo(kNEON)) { WebPInitPremultiplyNEON(); } #endif } #endif // FANCY_UPSAMPLING } libwebp-0.4.0/src/dsp/dsp.h0000644000014400001440000002023112255002107012353 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Speed-critical functions. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_DSP_DSP_H_ #define WEBP_DSP_DSP_H_ #include "../webp/types.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // CPU detection #if defined(_MSC_VER) && _MSC_VER > 1310 && \ (defined(_M_X64) || defined(_M_IX86)) #define WEBP_MSC_SSE2 // Visual C++ SSE2 targets #endif #if defined(__SSE2__) || defined(WEBP_MSC_SSE2) #define WEBP_USE_SSE2 #endif #if defined(__ANDROID__) && defined(__ARM_ARCH_7A__) #define WEBP_ANDROID_NEON // Android targets that might support NEON #endif #if defined(__ARM_NEON__) || defined(WEBP_ANDROID_NEON) #define WEBP_USE_NEON #endif typedef enum { kSSE2, kSSE3, kNEON } CPUFeature; // returns true if the CPU supports the feature. typedef int (*VP8CPUInfo)(CPUFeature feature); extern VP8CPUInfo VP8GetCPUInfo; //------------------------------------------------------------------------------ // Encoding // Transforms // VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms // will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4). typedef void (*VP8Idct)(const uint8_t* ref, const int16_t* in, uint8_t* dst, int do_two); typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out); typedef void (*VP8WHT)(const int16_t* in, int16_t* out); extern VP8Idct VP8ITransform; extern VP8Fdct VP8FTransform; extern VP8WHT VP8ITransformWHT; extern VP8WHT VP8FTransformWHT; // Predictions // *dst is the destination block. *top and *left can be NULL. typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left, const uint8_t* top); typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top); extern VP8Intra4Preds VP8EncPredLuma4; extern VP8IntraPreds VP8EncPredLuma16; extern VP8IntraPreds VP8EncPredChroma8; typedef int (*VP8Metric)(const uint8_t* pix, const uint8_t* ref); extern VP8Metric VP8SSE16x16, VP8SSE16x8, VP8SSE8x8, VP8SSE4x4; typedef int (*VP8WMetric)(const uint8_t* pix, const uint8_t* ref, const uint16_t* const weights); extern VP8WMetric VP8TDisto4x4, VP8TDisto16x16; typedef void (*VP8BlockCopy)(const uint8_t* src, uint8_t* dst); extern VP8BlockCopy VP8Copy4x4; // Quantization struct VP8Matrix; // forward declaration typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16], int n, const struct VP8Matrix* const mtx); extern VP8QuantizeBlock VP8EncQuantizeBlock; // specific to 2nd transform: typedef int (*VP8QuantizeBlockWHT)(int16_t in[16], int16_t out[16], const struct VP8Matrix* const mtx); extern VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT; // Collect histogram for susceptibility calculation and accumulate in histo[]. struct VP8Histogram; typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred, int start_block, int end_block, struct VP8Histogram* const histo); extern const int VP8DspScan[16 + 4 + 4]; extern VP8CHisto VP8CollectHistogram; void VP8EncDspInit(void); // must be called before using any of the above //------------------------------------------------------------------------------ // Decoding typedef void (*VP8DecIdct)(const int16_t* coeffs, uint8_t* dst); // when doing two transforms, coeffs is actually int16_t[2][16]. typedef void (*VP8DecIdct2)(const int16_t* coeffs, uint8_t* dst, int do_two); extern VP8DecIdct2 VP8Transform; extern VP8DecIdct VP8TransformAC3; extern VP8DecIdct VP8TransformUV; extern VP8DecIdct VP8TransformDC; extern VP8DecIdct VP8TransformDCUV; extern VP8WHT VP8TransformWHT; // *dst is the destination block, with stride BPS. Boundary samples are // assumed accessible when needed. typedef void (*VP8PredFunc)(uint8_t* dst); extern const VP8PredFunc VP8PredLuma16[/* NUM_B_DC_MODES */]; extern const VP8PredFunc VP8PredChroma8[/* NUM_B_DC_MODES */]; extern const VP8PredFunc VP8PredLuma4[/* NUM_BMODES */]; // simple filter (only for luma) typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh); extern VP8SimpleFilterFunc VP8SimpleVFilter16; extern VP8SimpleFilterFunc VP8SimpleHFilter16; extern VP8SimpleFilterFunc VP8SimpleVFilter16i; // filter 3 inner edges extern VP8SimpleFilterFunc VP8SimpleHFilter16i; // regular filter (on both macroblock edges and inner edges) typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride, int thresh, int ithresh, int hev_t); typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride, int thresh, int ithresh, int hev_t); // on outer edge extern VP8LumaFilterFunc VP8VFilter16; extern VP8LumaFilterFunc VP8HFilter16; extern VP8ChromaFilterFunc VP8VFilter8; extern VP8ChromaFilterFunc VP8HFilter8; // on inner edge extern VP8LumaFilterFunc VP8VFilter16i; // filtering 3 inner edges altogether extern VP8LumaFilterFunc VP8HFilter16i; extern VP8ChromaFilterFunc VP8VFilter8i; // filtering u and v altogether extern VP8ChromaFilterFunc VP8HFilter8i; // must be called before anything using the above void VP8DspInit(void); //------------------------------------------------------------------------------ // WebP I/O #define FANCY_UPSAMPLING // undefined to remove fancy upsampling support // Convert a pair of y/u/v lines together to the output rgb/a colorspace. // bottom_y can be NULL if only one line of output is needed (at top/bottom). typedef void (*WebPUpsampleLinePairFunc)( const uint8_t* top_y, const uint8_t* bottom_y, const uint8_t* top_u, const uint8_t* top_v, const uint8_t* cur_u, const uint8_t* cur_v, uint8_t* top_dst, uint8_t* bottom_dst, int len); #ifdef FANCY_UPSAMPLING // Fancy upsampling functions to convert YUV to RGB(A) modes extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */]; // Initializes SSE2 version of the fancy upsamplers. void WebPInitUpsamplersSSE2(void); // NEON version void WebPInitUpsamplersNEON(void); #endif // FANCY_UPSAMPLING // Point-sampling methods. typedef void (*WebPSampleLinePairFunc)( const uint8_t* top_y, const uint8_t* bottom_y, const uint8_t* u, const uint8_t* v, uint8_t* top_dst, uint8_t* bottom_dst, int len); extern const WebPSampleLinePairFunc WebPSamplers[/* MODE_LAST */]; // General function for converting two lines of ARGB or RGBA. // 'alpha_is_last' should be true if 0xff000000 is stored in memory as // as 0x00, 0x00, 0x00, 0xff (little endian). WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last); // YUV444->RGB converters typedef void (*WebPYUV444Converter)(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst, int len); extern const WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */]; // Main function to be called void WebPInitUpsamplers(void); //------------------------------------------------------------------------------ // Pre-multiply planes with alpha values // Apply alpha pre-multiply on an rgba, bgra or argb plane of size w * h. // alpha_first should be 0 for argb, 1 for rgba or bgra (where alpha is last). extern void (*WebPApplyAlphaMultiply)( uint8_t* rgba, int alpha_first, int w, int h, int stride); // Same, buf specifically for RGBA4444 format extern void (*WebPApplyAlphaMultiply4444)( uint8_t* rgba4444, int w, int h, int stride); // To be called first before using the above. void WebPInitPremultiply(void); void WebPInitPremultiplySSE2(void); // should not be called directly. void WebPInitPremultiplyNEON(void); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_DSP_DSP_H_ */ libwebp-0.4.0/src/dsp/dec_neon.c0000644000014400001440000004370112255002107013341 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // ARM NEON version of dsp functions and loop filtering. // // Authors: Somnath Banerjee (somnath@google.com) // Johann Koenig (johannkoenig@google.com) #include "./dsp.h" #if defined(WEBP_USE_NEON) #include "../dec/vp8i.h" #define QRegs "q0", "q1", "q2", "q3", \ "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" #define FLIP_SIGN_BIT2(a, b, s) \ "veor " #a "," #a "," #s " \n" \ "veor " #b "," #b "," #s " \n" \ #define FLIP_SIGN_BIT4(a, b, c, d, s) \ FLIP_SIGN_BIT2(a, b, s) \ FLIP_SIGN_BIT2(c, d, s) \ #define NEEDS_FILTER(p1, p0, q0, q1, thresh, mask) \ "vabd.u8 q15," #p0 "," #q0 " \n" /* abs(p0 - q0) */ \ "vabd.u8 q14," #p1 "," #q1 " \n" /* abs(p1 - q1) */ \ "vqadd.u8 q15, q15, q15 \n" /* abs(p0 - q0) * 2 */ \ "vshr.u8 q14, q14, #1 \n" /* abs(p1 - q1) / 2 */ \ "vqadd.u8 q15, q15, q14 \n" /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 */ \ "vdup.8 q14, " #thresh " \n" \ "vcge.u8 " #mask ", q14, q15 \n" /* mask <= thresh */ #define GET_BASE_DELTA(p1, p0, q0, q1, o) \ "vqsub.s8 q15," #q0 "," #p0 " \n" /* (q0 - p0) */ \ "vqsub.s8 " #o "," #p1 "," #q1 " \n" /* (p1 - q1) */ \ "vqadd.s8 " #o "," #o ", q15 \n" /* (p1 - q1) + 1 * (p0 - q0) */ \ "vqadd.s8 " #o "," #o ", q15 \n" /* (p1 - q1) + 2 * (p0 - q0) */ \ "vqadd.s8 " #o "," #o ", q15 \n" /* (p1 - q1) + 3 * (p0 - q0) */ #define DO_SIMPLE_FILTER(p0, q0, fl) \ "vmov.i8 q15, #0x03 \n" \ "vqadd.s8 q15, q15, " #fl " \n" /* filter1 = filter + 3 */ \ "vshr.s8 q15, q15, #3 \n" /* filter1 >> 3 */ \ "vqadd.s8 " #p0 "," #p0 ", q15 \n" /* p0 += filter1 */ \ \ "vmov.i8 q15, #0x04 \n" \ "vqadd.s8 q15, q15, " #fl " \n" /* filter1 = filter + 4 */ \ "vshr.s8 q15, q15, #3 \n" /* filter2 >> 3 */ \ "vqsub.s8 " #q0 "," #q0 ", q15 \n" /* q0 -= filter2 */ // Applies filter on 2 pixels (p0 and q0) #define DO_FILTER2(p1, p0, q0, q1, thresh) \ NEEDS_FILTER(p1, p0, q0, q1, thresh, q9) /* filter mask in q9 */ \ "vmov.i8 q10, #0x80 \n" /* sign bit */ \ FLIP_SIGN_BIT4(p1, p0, q0, q1, q10) /* convert to signed value */ \ GET_BASE_DELTA(p1, p0, q0, q1, q11) /* get filter level */ \ "vand q9, q9, q11 \n" /* apply filter mask */ \ DO_SIMPLE_FILTER(p0, q0, q9) /* apply filter */ \ FLIP_SIGN_BIT2(p0, q0, q10) // Load/Store vertical edge #define LOAD8x4(c1, c2, c3, c4, b1, b2, stride) \ "vld4.8 {" #c1"[0], " #c2"[0], " #c3"[0], " #c4"[0]}," #b1 "," #stride"\n" \ "vld4.8 {" #c1"[1], " #c2"[1], " #c3"[1], " #c4"[1]}," #b2 "," #stride"\n" \ "vld4.8 {" #c1"[2], " #c2"[2], " #c3"[2], " #c4"[2]}," #b1 "," #stride"\n" \ "vld4.8 {" #c1"[3], " #c2"[3], " #c3"[3], " #c4"[3]}," #b2 "," #stride"\n" \ "vld4.8 {" #c1"[4], " #c2"[4], " #c3"[4], " #c4"[4]}," #b1 "," #stride"\n" \ "vld4.8 {" #c1"[5], " #c2"[5], " #c3"[5], " #c4"[5]}," #b2 "," #stride"\n" \ "vld4.8 {" #c1"[6], " #c2"[6], " #c3"[6], " #c4"[6]}," #b1 "," #stride"\n" \ "vld4.8 {" #c1"[7], " #c2"[7], " #c3"[7], " #c4"[7]}," #b2 "," #stride"\n" #define STORE8x2(c1, c2, p, stride) \ "vst2.8 {" #c1"[0], " #c2"[0]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[1], " #c2"[1]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[2], " #c2"[2]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[3], " #c2"[3]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[4], " #c2"[4]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[5], " #c2"[5]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[6], " #c2"[6]}," #p "," #stride " \n" \ "vst2.8 {" #c1"[7], " #c2"[7]}," #p "," #stride " \n" //----------------------------------------------------------------------------- // Simple In-loop filtering (Paragraph 15.2) static void SimpleVFilter16NEON(uint8_t* p, int stride, int thresh) { __asm__ volatile ( "sub %[p], %[p], %[stride], lsl #1 \n" // p -= 2 * stride "vld1.u8 {q1}, [%[p]], %[stride] \n" // p1 "vld1.u8 {q2}, [%[p]], %[stride] \n" // p0 "vld1.u8 {q3}, [%[p]], %[stride] \n" // q0 "vld1.u8 {q12}, [%[p]] \n" // q1 DO_FILTER2(q1, q2, q3, q12, %[thresh]) "sub %[p], %[p], %[stride], lsl #1 \n" // p -= 2 * stride "vst1.u8 {q2}, [%[p]], %[stride] \n" // store op0 "vst1.u8 {q3}, [%[p]] \n" // store oq0 : [p] "+r"(p) : [stride] "r"(stride), [thresh] "r"(thresh) : "memory", QRegs ); } static void SimpleHFilter16NEON(uint8_t* p, int stride, int thresh) { __asm__ volatile ( "sub r4, %[p], #2 \n" // base1 = p - 2 "lsl r6, %[stride], #1 \n" // r6 = 2 * stride "add r5, r4, %[stride] \n" // base2 = base1 + stride LOAD8x4(d2, d3, d4, d5, [r4], [r5], r6) LOAD8x4(d24, d25, d26, d27, [r4], [r5], r6) "vswp d3, d24 \n" // p1:q1 p0:q3 "vswp d5, d26 \n" // q0:q2 q1:q4 "vswp q2, q12 \n" // p1:q1 p0:q2 q0:q3 q1:q4 DO_FILTER2(q1, q2, q12, q13, %[thresh]) "sub %[p], %[p], #1 \n" // p - 1 "vswp d5, d24 \n" STORE8x2(d4, d5, [%[p]], %[stride]) STORE8x2(d24, d25, [%[p]], %[stride]) : [p] "+r"(p) : [stride] "r"(stride), [thresh] "r"(thresh) : "memory", "r4", "r5", "r6", QRegs ); } static void SimpleVFilter16iNEON(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4 * stride; SimpleVFilter16NEON(p, stride, thresh); } } static void SimpleHFilter16iNEON(uint8_t* p, int stride, int thresh) { int k; for (k = 3; k > 0; --k) { p += 4; SimpleHFilter16NEON(p, stride, thresh); } } //----------------------------------------------------------------------------- // Inverse transforms (Paragraph 14.4) static void TransformOne(const int16_t* in, uint8_t* dst) { const int kBPS = BPS; const int16_t constants[] = {20091, 17734, 0, 0}; /* kC1, kC2. Padded because vld1.16 loads 8 bytes * Technically these are unsigned but vqdmulh is only available in signed. * vqdmulh returns high half (effectively >> 16) but also doubles the value, * changing the >> 16 to >> 15 and requiring an additional >> 1. * We use this to our advantage with kC2. The canonical value is 35468. * However, the high bit is set so treating it as signed will give incorrect * results. We avoid this by down shifting by 1 here to clear the highest bit. * Combined with the doubling effect of vqdmulh we get >> 16. * This can not be applied to kC1 because the lowest bit is set. Down shifting * the constant would reduce precision. */ /* libwebp uses a trick to avoid some extra addition that libvpx does. * Instead of: * temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16); * libwebp adds 1 << 16 to cospi8sqrt2minus1 (kC1). However, this causes the * same issue with kC1 and vqdmulh that we work around by down shifting kC2 */ /* Adapted from libvpx: vp8/common/arm/neon/shortidct4x4llm_neon.asm */ __asm__ volatile ( "vld1.16 {q1, q2}, [%[in]] \n" "vld1.16 {d0}, [%[constants]] \n" /* d2: in[0] * d3: in[8] * d4: in[4] * d5: in[12] */ "vswp d3, d4 \n" /* q8 = {in[4], in[12]} * kC1 * 2 >> 16 * q9 = {in[4], in[12]} * kC2 >> 16 */ "vqdmulh.s16 q8, q2, d0[0] \n" "vqdmulh.s16 q9, q2, d0[1] \n" /* d22 = a = in[0] + in[8] * d23 = b = in[0] - in[8] */ "vqadd.s16 d22, d2, d3 \n" "vqsub.s16 d23, d2, d3 \n" /* The multiplication should be x * kC1 >> 16 * However, with vqdmulh we get x * kC1 * 2 >> 16 * (multiply, double, return high half) * We avoided this in kC2 by pre-shifting the constant. * q8 = in[4]/[12] * kC1 >> 16 */ "vshr.s16 q8, q8, #1 \n" /* Add {in[4], in[12]} back after the multiplication. This is handled by * adding 1 << 16 to kC1 in the libwebp C code. */ "vqadd.s16 q8, q2, q8 \n" /* d20 = c = in[4]*kC2 - in[12]*kC1 * d21 = d = in[4]*kC1 + in[12]*kC2 */ "vqsub.s16 d20, d18, d17 \n" "vqadd.s16 d21, d19, d16 \n" /* d2 = tmp[0] = a + d * d3 = tmp[1] = b + c * d4 = tmp[2] = b - c * d5 = tmp[3] = a - d */ "vqadd.s16 d2, d22, d21 \n" "vqadd.s16 d3, d23, d20 \n" "vqsub.s16 d4, d23, d20 \n" "vqsub.s16 d5, d22, d21 \n" "vzip.16 q1, q2 \n" "vzip.16 q1, q2 \n" "vswp d3, d4 \n" /* q8 = {tmp[4], tmp[12]} * kC1 * 2 >> 16 * q9 = {tmp[4], tmp[12]} * kC2 >> 16 */ "vqdmulh.s16 q8, q2, d0[0] \n" "vqdmulh.s16 q9, q2, d0[1] \n" /* d22 = a = tmp[0] + tmp[8] * d23 = b = tmp[0] - tmp[8] */ "vqadd.s16 d22, d2, d3 \n" "vqsub.s16 d23, d2, d3 \n" /* See long winded explanations prior */ "vshr.s16 q8, q8, #1 \n" "vqadd.s16 q8, q2, q8 \n" /* d20 = c = in[4]*kC2 - in[12]*kC1 * d21 = d = in[4]*kC1 + in[12]*kC2 */ "vqsub.s16 d20, d18, d17 \n" "vqadd.s16 d21, d19, d16 \n" /* d2 = tmp[0] = a + d * d3 = tmp[1] = b + c * d4 = tmp[2] = b - c * d5 = tmp[3] = a - d */ "vqadd.s16 d2, d22, d21 \n" "vqadd.s16 d3, d23, d20 \n" "vqsub.s16 d4, d23, d20 \n" "vqsub.s16 d5, d22, d21 \n" "vld1.32 d6[0], [%[dst]], %[kBPS] \n" "vld1.32 d6[1], [%[dst]], %[kBPS] \n" "vld1.32 d7[0], [%[dst]], %[kBPS] \n" "vld1.32 d7[1], [%[dst]], %[kBPS] \n" "sub %[dst], %[dst], %[kBPS], lsl #2 \n" /* (val) + 4 >> 3 */ "vrshr.s16 d2, d2, #3 \n" "vrshr.s16 d3, d3, #3 \n" "vrshr.s16 d4, d4, #3 \n" "vrshr.s16 d5, d5, #3 \n" "vzip.16 q1, q2 \n" "vzip.16 q1, q2 \n" /* Must accumulate before saturating */ "vmovl.u8 q8, d6 \n" "vmovl.u8 q9, d7 \n" "vqadd.s16 q1, q1, q8 \n" "vqadd.s16 q2, q2, q9 \n" "vqmovun.s16 d0, q1 \n" "vqmovun.s16 d1, q2 \n" "vst1.32 d0[0], [%[dst]], %[kBPS] \n" "vst1.32 d0[1], [%[dst]], %[kBPS] \n" "vst1.32 d1[0], [%[dst]], %[kBPS] \n" "vst1.32 d1[1], [%[dst]] \n" : [in] "+r"(in), [dst] "+r"(dst) /* modified registers */ : [kBPS] "r"(kBPS), [constants] "r"(constants) /* constants */ : "memory", "q0", "q1", "q2", "q8", "q9", "q10", "q11" /* clobbered */ ); } static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) { TransformOne(in, dst); if (do_two) { TransformOne(in + 16, dst + 4); } } static void TransformDC(const int16_t* in, uint8_t* dst) { const int DC = (in[0] + 4) >> 3; const int kBPS = BPS; __asm__ volatile ( "vdup.16 q1, %[DC] \n" "vld1.32 d0[0], [%[dst]], %[kBPS] \n" "vld1.32 d1[0], [%[dst]], %[kBPS] \n" "vld1.32 d0[1], [%[dst]], %[kBPS] \n" "vld1.32 d1[1], [%[dst]], %[kBPS] \n" "sub %[dst], %[dst], %[kBPS], lsl #2 \n" // add DC and convert to s16. "vaddw.u8 q2, q1, d0 \n" "vaddw.u8 q3, q1, d1 \n" // convert back to u8 with saturation "vqmovun.s16 d0, q2 \n" "vqmovun.s16 d1, q3 \n" "vst1.32 d0[0], [%[dst]], %[kBPS] \n" "vst1.32 d1[0], [%[dst]], %[kBPS] \n" "vst1.32 d0[1], [%[dst]], %[kBPS] \n" "vst1.32 d1[1], [%[dst]] \n" : [in] "+r"(in), [dst] "+r"(dst) /* modified registers */ : [kBPS] "r"(kBPS), /* constants */ [DC] "r"(DC) : "memory", "q0", "q1", "q2", "q3" /* clobbered */ ); } static void TransformWHT(const int16_t* in, int16_t* out) { const int kStep = 32; // The store is only incrementing the pointer as if we // had stored a single byte. __asm__ volatile ( // part 1 // load data into q0, q1 "vld1.16 {q0, q1}, [%[in]] \n" "vaddl.s16 q2, d0, d3 \n" // a0 = in[0] + in[12] "vaddl.s16 q3, d1, d2 \n" // a1 = in[4] + in[8] "vsubl.s16 q10, d1, d2 \n" // a2 = in[4] - in[8] "vsubl.s16 q11, d0, d3 \n" // a3 = in[0] - in[12] "vadd.s32 q0, q2, q3 \n" // tmp[0] = a0 + a1 "vsub.s32 q2, q2, q3 \n" // tmp[8] = a0 - a1 "vadd.s32 q1, q11, q10 \n" // tmp[4] = a3 + a2 "vsub.s32 q3, q11, q10 \n" // tmp[12] = a3 - a2 // Transpose // q0 = tmp[0, 4, 8, 12], q1 = tmp[2, 6, 10, 14] // q2 = tmp[1, 5, 9, 13], q3 = tmp[3, 7, 11, 15] "vswp d1, d4 \n" // vtrn.64 q0, q2 "vswp d3, d6 \n" // vtrn.64 q1, q3 "vtrn.32 q0, q1 \n" "vtrn.32 q2, q3 \n" "vmov.s32 q10, #3 \n" // dc = 3 "vadd.s32 q0, q0, q10 \n" // dc = tmp[0] + 3 "vadd.s32 q12, q0, q3 \n" // a0 = dc + tmp[3] "vadd.s32 q13, q1, q2 \n" // a1 = tmp[1] + tmp[2] "vsub.s32 q8, q1, q2 \n" // a2 = tmp[1] - tmp[2] "vsub.s32 q9, q0, q3 \n" // a3 = dc - tmp[3] "vadd.s32 q0, q12, q13 \n" "vshrn.s32 d0, q0, #3 \n" // (a0 + a1) >> 3 "vadd.s32 q1, q9, q8 \n" "vshrn.s32 d1, q1, #3 \n" // (a3 + a2) >> 3 "vsub.s32 q2, q12, q13 \n" "vshrn.s32 d2, q2, #3 \n" // (a0 - a1) >> 3 "vsub.s32 q3, q9, q8 \n" "vshrn.s32 d3, q3, #3 \n" // (a3 - a2) >> 3 // set the results to output "vst1.16 d0[0], [%[out]], %[kStep] \n" "vst1.16 d1[0], [%[out]], %[kStep] \n" "vst1.16 d2[0], [%[out]], %[kStep] \n" "vst1.16 d3[0], [%[out]], %[kStep] \n" "vst1.16 d0[1], [%[out]], %[kStep] \n" "vst1.16 d1[1], [%[out]], %[kStep] \n" "vst1.16 d2[1], [%[out]], %[kStep] \n" "vst1.16 d3[1], [%[out]], %[kStep] \n" "vst1.16 d0[2], [%[out]], %[kStep] \n" "vst1.16 d1[2], [%[out]], %[kStep] \n" "vst1.16 d2[2], [%[out]], %[kStep] \n" "vst1.16 d3[2], [%[out]], %[kStep] \n" "vst1.16 d0[3], [%[out]], %[kStep] \n" "vst1.16 d1[3], [%[out]], %[kStep] \n" "vst1.16 d2[3], [%[out]], %[kStep] \n" "vst1.16 d3[3], [%[out]], %[kStep] \n" : [out] "+r"(out) // modified registers : [in] "r"(in), [kStep] "r"(kStep) // constants : "memory", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13" // clobbered ); } #endif // WEBP_USE_NEON //------------------------------------------------------------------------------ // Entry point extern void VP8DspInitNEON(void); void VP8DspInitNEON(void) { #if defined(WEBP_USE_NEON) VP8Transform = TransformTwo; VP8TransformAC3 = TransformOne; // no special code here VP8TransformDC = TransformDC; VP8TransformWHT = TransformWHT; VP8SimpleVFilter16 = SimpleVFilter16NEON; VP8SimpleHFilter16 = SimpleHFilter16NEON; VP8SimpleVFilter16i = SimpleVFilter16iNEON; VP8SimpleHFilter16i = SimpleHFilter16iNEON; #endif // WEBP_USE_NEON } libwebp-0.4.0/src/dsp/yuv.c0000644000014400001440000001526112255002107012412 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // YUV->RGB conversion function // // Author: Skal (pascal.massimino@gmail.com) #include "./yuv.h" #if defined(WEBP_YUV_USE_TABLE) static int done = 0; static WEBP_INLINE uint8_t clip(int v, int max_value) { return v < 0 ? 0 : v > max_value ? max_value : v; } int16_t VP8kVToR[256], VP8kUToB[256]; int32_t VP8kVToG[256], VP8kUToG[256]; uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN]; uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN]; void VP8YUVInit(void) { int i; if (done) { return; } #ifndef USE_YUVj for (i = 0; i < 256; ++i) { VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX; VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF; VP8kVToG[i] = -45773 * (i - 128); VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX; } for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) { const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX; VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255); VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15); } #else for (i = 0; i < 256; ++i) { VP8kVToR[i] = (91881 * (i - 128) + YUV_HALF) >> YUV_FIX; VP8kUToG[i] = -22554 * (i - 128) + YUV_HALF; VP8kVToG[i] = -46802 * (i - 128); VP8kUToB[i] = (116130 * (i - 128) + YUV_HALF) >> YUV_FIX; } for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) { const int k = i; VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255); VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15); } #endif done = 1; } #else void VP8YUVInit(void) {} #endif // WEBP_YUV_USE_TABLE //----------------------------------------------------------------------------- // SSE2 extras #if defined(WEBP_USE_SSE2) #ifdef FANCY_UPSAMPLING #include #include // for memcpy typedef union { // handy struct for converting SSE2 registers int32_t i32[4]; uint8_t u8[16]; __m128i m; } VP8kCstSSE2; static int done_sse2 = 0; static VP8kCstSSE2 VP8kUtoRGBA[256], VP8kVtoRGBA[256], VP8kYtoRGBA[256]; void VP8YUVInitSSE2(void) { if (!done_sse2) { int i; for (i = 0; i < 256; ++i) { VP8kYtoRGBA[i].i32[0] = VP8kYtoRGBA[i].i32[1] = VP8kYtoRGBA[i].i32[2] = (i - 16) * kYScale + YUV_HALF2; VP8kYtoRGBA[i].i32[3] = 0xff << YUV_FIX2; VP8kUtoRGBA[i].i32[0] = 0; VP8kUtoRGBA[i].i32[1] = -kUToG * (i - 128); VP8kUtoRGBA[i].i32[2] = kUToB * (i - 128); VP8kUtoRGBA[i].i32[3] = 0; VP8kVtoRGBA[i].i32[0] = kVToR * (i - 128); VP8kVtoRGBA[i].i32[1] = -kVToG * (i - 128); VP8kVtoRGBA[i].i32[2] = 0; VP8kVtoRGBA[i].i32[3] = 0; } done_sse2 = 1; } } static WEBP_INLINE __m128i VP8GetRGBA32b(int y, int u, int v) { const __m128i u_part = _mm_loadu_si128(&VP8kUtoRGBA[u].m); const __m128i v_part = _mm_loadu_si128(&VP8kVtoRGBA[v].m); const __m128i y_part = _mm_loadu_si128(&VP8kYtoRGBA[y].m); const __m128i uv_part = _mm_add_epi32(u_part, v_part); const __m128i rgba1 = _mm_add_epi32(y_part, uv_part); const __m128i rgba2 = _mm_srai_epi32(rgba1, YUV_FIX2); return rgba2; } static WEBP_INLINE void VP8YuvToRgbSSE2(uint8_t y, uint8_t u, uint8_t v, uint8_t* const rgb) { const __m128i tmp0 = VP8GetRGBA32b(y, u, v); const __m128i tmp1 = _mm_packs_epi32(tmp0, tmp0); const __m128i tmp2 = _mm_packus_epi16(tmp1, tmp1); // Note: we store 8 bytes at a time, not 3 bytes! -> memory stomp _mm_storel_epi64((__m128i*)rgb, tmp2); } static WEBP_INLINE void VP8YuvToBgrSSE2(uint8_t y, uint8_t u, uint8_t v, uint8_t* const bgr) { const __m128i tmp0 = VP8GetRGBA32b(y, u, v); const __m128i tmp1 = _mm_shuffle_epi32(tmp0, _MM_SHUFFLE(3, 0, 1, 2)); const __m128i tmp2 = _mm_packs_epi32(tmp1, tmp1); const __m128i tmp3 = _mm_packus_epi16(tmp2, tmp2); // Note: we store 8 bytes at a time, not 3 bytes! -> memory stomp _mm_storel_epi64((__m128i*)bgr, tmp3); } void VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst) { int n; for (n = 0; n < 32; n += 4) { const __m128i tmp0_1 = VP8GetRGBA32b(y[n + 0], u[n + 0], v[n + 0]); const __m128i tmp0_2 = VP8GetRGBA32b(y[n + 1], u[n + 1], v[n + 1]); const __m128i tmp0_3 = VP8GetRGBA32b(y[n + 2], u[n + 2], v[n + 2]); const __m128i tmp0_4 = VP8GetRGBA32b(y[n + 3], u[n + 3], v[n + 3]); const __m128i tmp1_1 = _mm_packs_epi32(tmp0_1, tmp0_2); const __m128i tmp1_2 = _mm_packs_epi32(tmp0_3, tmp0_4); const __m128i tmp2 = _mm_packus_epi16(tmp1_1, tmp1_2); _mm_storeu_si128((__m128i*)dst, tmp2); dst += 4 * 4; } } void VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst) { int n; for (n = 0; n < 32; n += 2) { const __m128i tmp0_1 = VP8GetRGBA32b(y[n + 0], u[n + 0], v[n + 0]); const __m128i tmp0_2 = VP8GetRGBA32b(y[n + 1], u[n + 1], v[n + 1]); const __m128i tmp1_1 = _mm_shuffle_epi32(tmp0_1, _MM_SHUFFLE(3, 0, 1, 2)); const __m128i tmp1_2 = _mm_shuffle_epi32(tmp0_2, _MM_SHUFFLE(3, 0, 1, 2)); const __m128i tmp2_1 = _mm_packs_epi32(tmp1_1, tmp1_2); const __m128i tmp3 = _mm_packus_epi16(tmp2_1, tmp2_1); _mm_storel_epi64((__m128i*)dst, tmp3); dst += 4 * 2; } } void VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst) { int n; uint8_t tmp0[2 * 3 + 5 + 15]; uint8_t* const tmp = (uint8_t*)((uintptr_t)(tmp0 + 15) & ~15); // align for (n = 0; n < 30; ++n) { // we directly stomp the *dst memory VP8YuvToRgbSSE2(y[n], u[n], v[n], dst + n * 3); } // Last two pixels are special: we write in a tmp buffer before sending // to dst. VP8YuvToRgbSSE2(y[n + 0], u[n + 0], v[n + 0], tmp + 0); VP8YuvToRgbSSE2(y[n + 1], u[n + 1], v[n + 1], tmp + 3); memcpy(dst + n * 3, tmp, 2 * 3); } void VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst) { int n; uint8_t tmp0[2 * 3 + 5 + 15]; uint8_t* const tmp = (uint8_t*)((uintptr_t)(tmp0 + 15) & ~15); // align for (n = 0; n < 30; ++n) { VP8YuvToBgrSSE2(y[n], u[n], v[n], dst + n * 3); } VP8YuvToBgrSSE2(y[n + 0], u[n + 0], v[n + 0], tmp + 0); VP8YuvToBgrSSE2(y[n + 1], u[n + 1], v[n + 1], tmp + 3); memcpy(dst + n * 3, tmp, 2 * 3); } #else void VP8YUVInitSSE2(void) {} #endif // FANCY_UPSAMPLING #endif // WEBP_USE_SSE2 libwebp-0.4.0/src/dsp/upsampling_sse2.c0000644000014400001440000002677512255002107014716 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // SSE2 version of YUV to RGB upsampling functions. // // Author: somnath@google.com (Somnath Banerjee) #include "./dsp.h" #if defined(WEBP_USE_SSE2) #include #include #include #include "./yuv.h" #ifdef FANCY_UPSAMPLING // We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows // u = (9*a + 3*b + 3*c + d + 8) / 16 // = (a + (a + 3*b + 3*c + d) / 8 + 1) / 2 // = (a + m + 1) / 2 // where m = (a + 3*b + 3*c + d) / 8 // = ((a + b + c + d) / 2 + b + c) / 4 // // Let's say k = (a + b + c + d) / 4. // We can compute k as // k = (s + t + 1) / 2 - ((a^d) | (b^c) | (s^t)) & 1 // where s = (a + d + 1) / 2 and t = (b + c + 1) / 2 // // Then m can be written as // m = (k + t + 1) / 2 - (((b^c) & (s^t)) | (k^t)) & 1 // Computes out = (k + in + 1) / 2 - ((ij & (s^t)) | (k^in)) & 1 #define GET_M(ij, in, out) do { \ const __m128i tmp0 = _mm_avg_epu8(k, (in)); /* (k + in + 1) / 2 */ \ const __m128i tmp1 = _mm_and_si128((ij), st); /* (ij) & (s^t) */ \ const __m128i tmp2 = _mm_xor_si128(k, (in)); /* (k^in) */ \ const __m128i tmp3 = _mm_or_si128(tmp1, tmp2); /* ((ij) & (s^t)) | (k^in) */\ const __m128i tmp4 = _mm_and_si128(tmp3, one); /* & 1 -> lsb_correction */ \ (out) = _mm_sub_epi8(tmp0, tmp4); /* (k + in + 1) / 2 - lsb_correction */ \ } while (0) // pack and store two alternating pixel rows #define PACK_AND_STORE(a, b, da, db, out) do { \ const __m128i t_a = _mm_avg_epu8(a, da); /* (9a + 3b + 3c + d + 8) / 16 */ \ const __m128i t_b = _mm_avg_epu8(b, db); /* (3a + 9b + c + 3d + 8) / 16 */ \ const __m128i t_1 = _mm_unpacklo_epi8(t_a, t_b); \ const __m128i t_2 = _mm_unpackhi_epi8(t_a, t_b); \ _mm_store_si128(((__m128i*)(out)) + 0, t_1); \ _mm_store_si128(((__m128i*)(out)) + 1, t_2); \ } while (0) // Loads 17 pixels each from rows r1 and r2 and generates 32 pixels. #define UPSAMPLE_32PIXELS(r1, r2, out) { \ const __m128i one = _mm_set1_epi8(1); \ const __m128i a = _mm_loadu_si128((__m128i*)&(r1)[0]); \ const __m128i b = _mm_loadu_si128((__m128i*)&(r1)[1]); \ const __m128i c = _mm_loadu_si128((__m128i*)&(r2)[0]); \ const __m128i d = _mm_loadu_si128((__m128i*)&(r2)[1]); \ \ const __m128i s = _mm_avg_epu8(a, d); /* s = (a + d + 1) / 2 */ \ const __m128i t = _mm_avg_epu8(b, c); /* t = (b + c + 1) / 2 */ \ const __m128i st = _mm_xor_si128(s, t); /* st = s^t */ \ \ const __m128i ad = _mm_xor_si128(a, d); /* ad = a^d */ \ const __m128i bc = _mm_xor_si128(b, c); /* bc = b^c */ \ \ const __m128i t1 = _mm_or_si128(ad, bc); /* (a^d) | (b^c) */ \ const __m128i t2 = _mm_or_si128(t1, st); /* (a^d) | (b^c) | (s^t) */ \ const __m128i t3 = _mm_and_si128(t2, one); /* (a^d) | (b^c) | (s^t) & 1 */ \ const __m128i t4 = _mm_avg_epu8(s, t); \ const __m128i k = _mm_sub_epi8(t4, t3); /* k = (a + b + c + d) / 4 */ \ __m128i diag1, diag2; \ \ GET_M(bc, t, diag1); /* diag1 = (a + 3b + 3c + d) / 8 */ \ GET_M(ad, s, diag2); /* diag2 = (3a + b + c + 3d) / 8 */ \ \ /* pack the alternate pixels */ \ PACK_AND_STORE(a, b, diag1, diag2, out + 0); /* store top */ \ PACK_AND_STORE(c, d, diag2, diag1, out + 2 * 32); /* store bottom */ \ } // Turn the macro into a function for reducing code-size when non-critical static void Upsample32Pixels(const uint8_t r1[], const uint8_t r2[], uint8_t* const out) { UPSAMPLE_32PIXELS(r1, r2, out); } #define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) { \ uint8_t r1[17], r2[17]; \ memcpy(r1, (tb), (num_pixels)); \ memcpy(r2, (bb), (num_pixels)); \ /* replicate last byte */ \ memset(r1 + (num_pixels), r1[(num_pixels) - 1], 17 - (num_pixels)); \ memset(r2 + (num_pixels), r2[(num_pixels) - 1], 17 - (num_pixels)); \ /* using the shared function instead of the macro saves ~3k code size */ \ Upsample32Pixels(r1, r2, out); \ } #define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, \ top_dst, bottom_dst, cur_x, num_pixels) { \ int n; \ for (n = 0; n < (num_pixels); ++n) { \ FUNC(top_y[(cur_x) + n], r_u[n], r_v[n], \ top_dst + ((cur_x) + n) * XSTEP); \ } \ if (bottom_y != NULL) { \ for (n = 0; n < (num_pixels); ++n) { \ FUNC(bottom_y[(cur_x) + n], r_u[64 + n], r_v[64 + n], \ bottom_dst + ((cur_x) + n) * XSTEP); \ } \ } \ } #define CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, \ top_dst, bottom_dst, cur_x) do { \ FUNC##32(top_y + (cur_x), r_u, r_v, top_dst + (cur_x) * XSTEP); \ if (bottom_y != NULL) { \ FUNC##32(bottom_y + (cur_x), r_u + 64, r_v + 64, \ bottom_dst + (cur_x) * XSTEP); \ } \ } while (0) #define SSE2_UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ const uint8_t* top_u, const uint8_t* top_v, \ const uint8_t* cur_u, const uint8_t* cur_v, \ uint8_t* top_dst, uint8_t* bottom_dst, int len) { \ int uv_pos, pos; \ /* 16byte-aligned array to cache reconstructed u and v */ \ uint8_t uv_buf[4 * 32 + 15]; \ uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \ uint8_t* const r_v = r_u + 32; \ \ assert(top_y != NULL); \ { /* Treat the first pixel in regular way */ \ const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1; \ const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1; \ const int u0_t = (top_u[0] + u_diag) >> 1; \ const int v0_t = (top_v[0] + v_diag) >> 1; \ FUNC(top_y[0], u0_t, v0_t, top_dst); \ if (bottom_y != NULL) { \ const int u0_b = (cur_u[0] + u_diag) >> 1; \ const int v0_b = (cur_v[0] + v_diag) >> 1; \ FUNC(bottom_y[0], u0_b, v0_b, bottom_dst); \ } \ } \ /* For UPSAMPLE_32PIXELS, 17 u/v values must be read-able for each block */ \ for (pos = 1, uv_pos = 0; pos + 32 + 1 <= len; pos += 32, uv_pos += 16) { \ UPSAMPLE_32PIXELS(top_u + uv_pos, cur_u + uv_pos, r_u); \ UPSAMPLE_32PIXELS(top_v + uv_pos, cur_v + uv_pos, r_v); \ CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, pos); \ } \ if (len > 1) { \ const int left_over = ((len + 1) >> 1) - (pos >> 1); \ assert(left_over > 0); \ UPSAMPLE_LAST_BLOCK(top_u + uv_pos, cur_u + uv_pos, left_over, r_u); \ UPSAMPLE_LAST_BLOCK(top_v + uv_pos, cur_v + uv_pos, left_over, r_v); \ CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, \ pos, len - pos); \ } \ } // SSE2 variants of the fancy upsampler. SSE2_UPSAMPLE_FUNC(UpsampleRgbLinePairSSE2, VP8YuvToRgb, 3) SSE2_UPSAMPLE_FUNC(UpsampleBgrLinePairSSE2, VP8YuvToBgr, 3) SSE2_UPSAMPLE_FUNC(UpsampleRgbaLinePairSSE2, VP8YuvToRgba, 4) SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePairSSE2, VP8YuvToBgra, 4) #undef GET_M #undef PACK_AND_STORE #undef UPSAMPLE_32PIXELS #undef UPSAMPLE_LAST_BLOCK #undef CONVERT2RGB #undef CONVERT2RGB_32 #undef SSE2_UPSAMPLE_FUNC #endif // FANCY_UPSAMPLING #endif // WEBP_USE_SSE2 //------------------------------------------------------------------------------ #ifdef FANCY_UPSAMPLING extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */]; void WebPInitUpsamplersSSE2(void) { #if defined(WEBP_USE_SSE2) VP8YUVInitSSE2(); WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePairSSE2; WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePairSSE2; WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePairSSE2; WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePairSSE2; #endif // WEBP_USE_SSE2 } void WebPInitPremultiplySSE2(void) { #if defined(WEBP_USE_SSE2) WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePairSSE2; WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePairSSE2; #endif // WEBP_USE_SSE2 } #else // this empty function is to avoid an empty .o void WebPInitPremultiplySSE2(void) {} #endif // FANCY_UPSAMPLING libwebp-0.4.0/src/dsp/lossless.h0000644000014400001440000002033712255002107013443 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Image transforms and color space conversion methods for lossless decoder. // // Authors: Vikas Arora (vikaas.arora@gmail.com) // Jyrki Alakuijala (jyrki@google.com) #ifndef WEBP_DSP_LOSSLESS_H_ #define WEBP_DSP_LOSSLESS_H_ #include "../webp/types.h" #include "../webp/decode.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // typedef uint32_t (*VP8LPredClampedAddSubFunc)(uint32_t c0, uint32_t c1, uint32_t c2); typedef uint32_t (*VP8LPredSelectFunc)(uint32_t c0, uint32_t c1, uint32_t c2); typedef void (*VP8LSubtractGreenFromBlueAndRedFunc)(uint32_t* argb_data, int num_pixs); typedef void (*VP8LAddGreenToBlueAndRedFunc)(uint32_t* data_start, const uint32_t* data_end); extern VP8LPredClampedAddSubFunc VP8LClampedAddSubtractFull; extern VP8LPredClampedAddSubFunc VP8LClampedAddSubtractHalf; extern VP8LPredSelectFunc VP8LSelect; extern VP8LSubtractGreenFromBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed; extern VP8LAddGreenToBlueAndRedFunc VP8LAddGreenToBlueAndRed; // Must be called before calling any of the above methods. void VP8LDspInit(void); //------------------------------------------------------------------------------ // Image transforms. struct VP8LTransform; // Defined in dec/vp8li.h. // Performs inverse transform of data given transform information, start and end // rows. Transform will be applied to rows [row_start, row_end[. // The *in and *out pointers refer to source and destination data respectively // corresponding to the intermediate row (row_start). void VP8LInverseTransform(const struct VP8LTransform* const transform, int row_start, int row_end, const uint32_t* const in, uint32_t* const out); // Similar to the static method ColorIndexInverseTransform() that is part of // lossless.c, but used only for alpha decoding. It takes uint8_t (rather than // uint32_t) arguments for 'src' and 'dst'. void VP8LColorIndexInverseTransformAlpha( const struct VP8LTransform* const transform, int y_start, int y_end, const uint8_t* src, uint8_t* dst); void VP8LResidualImage(int width, int height, int bits, uint32_t* const argb, uint32_t* const argb_scratch, uint32_t* const image); void VP8LColorSpaceTransform(int width, int height, int bits, int step, uint32_t* const argb, uint32_t* image); //------------------------------------------------------------------------------ // Color space conversion. // Converts from BGRA to other color spaces. void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels, WEBP_CSP_MODE out_colorspace, uint8_t* const rgba); //------------------------------------------------------------------------------ // Misc methods. // Computes sampled size of 'size' when sampling using 'sampling bits'. static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size, uint32_t sampling_bits) { return (size + (1 << sampling_bits) - 1) >> sampling_bits; } // Faster logarithm for integers. Small values use a look-up table. #define LOG_LOOKUP_IDX_MAX 256 extern const float kLog2Table[LOG_LOOKUP_IDX_MAX]; extern const float kSLog2Table[LOG_LOOKUP_IDX_MAX]; float VP8LFastLog2Slow(int v); float VP8LFastSLog2Slow(int v); static WEBP_INLINE float VP8LFastLog2(int v) { return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v); } // Fast calculation of v * log2(v) for integer input. static WEBP_INLINE float VP8LFastSLog2(int v) { return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v); } // ----------------------------------------------------------------------------- // PrefixEncode() // use GNU builtins where available. #if defined(__GNUC__) && \ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return 31 ^ __builtin_clz(n); } #elif defined(_MSC_VER) && _MSC_VER > 1310 && \ (defined(_M_X64) || defined(_M_IX86)) #include #pragma intrinsic(_BitScanReverse) static WEBP_INLINE int BitsLog2Floor(uint32_t n) { unsigned long first_set_bit; _BitScanReverse(&first_set_bit, n); return first_set_bit; } #else // Returns (int)floor(log2(n)). n must be > 0. static WEBP_INLINE int BitsLog2Floor(uint32_t n) { int log = 0; uint32_t value = n; int i; for (i = 4; i >= 0; --i) { const int shift = (1 << i); const uint32_t x = value >> shift; if (x != 0) { value = x; log += shift; } } return log; } #endif static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) { const int log_floor = BitsLog2Floor(n); if (n == (n & ~(n - 1))) // zero or a power of two. return log_floor; else return log_floor + 1; } // Splitting of distance and length codes into prefixes and // extra bits. The prefixes are encoded with an entropy code // while the extra bits are stored just as normal bits. static WEBP_INLINE void VP8LPrefixEncodeBitsNoLUT(int distance, int* const code, int* const extra_bits) { const int highest_bit = BitsLog2Floor(--distance); const int second_highest_bit = (distance >> (highest_bit - 1)) & 1; *extra_bits = highest_bit - 1; *code = 2 * highest_bit + second_highest_bit; } static WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code, int* const extra_bits, int* const extra_bits_value) { const int highest_bit = BitsLog2Floor(--distance); const int second_highest_bit = (distance >> (highest_bit - 1)) & 1; *extra_bits = highest_bit - 1; *extra_bits_value = distance & ((1 << *extra_bits) - 1); *code = 2 * highest_bit + second_highest_bit; } #define PREFIX_LOOKUP_IDX_MAX 512 typedef struct { int8_t code_; int8_t extra_bits_; } VP8LPrefixCode; // These tables are derived using VP8LPrefixEncodeNoLUT. extern const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX]; extern const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX]; static WEBP_INLINE void VP8LPrefixEncodeBits(int distance, int* const code, int* const extra_bits) { if (distance < PREFIX_LOOKUP_IDX_MAX) { const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance]; *code = prefix_code.code_; *extra_bits = prefix_code.extra_bits_; } else { VP8LPrefixEncodeBitsNoLUT(distance, code, extra_bits); } } static WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code, int* const extra_bits, int* const extra_bits_value) { if (distance < PREFIX_LOOKUP_IDX_MAX) { const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance]; *code = prefix_code.code_; *extra_bits = prefix_code.extra_bits_; *extra_bits_value = kPrefixEncodeExtraBitsValue[distance]; } else { VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value); } } // In-place difference of each component with mod 256. static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) { const uint32_t alpha_and_green = 0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u); const uint32_t red_and_blue = 0xff00ff00u + (a & 0x00ff00ffu) - (b & 0x00ff00ffu); return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu); } void VP8LBundleColorMap(const uint8_t* const row, int width, int xbits, uint32_t* const dst); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_DSP_LOSSLESS_H_ libwebp-0.4.0/src/dsp/yuv.h0000644000014400001440000002562212255002107012421 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // inline YUV<->RGB conversion function // // The exact naming is Y'CbCr, following the ITU-R BT.601 standard. // More information at: http://en.wikipedia.org/wiki/YCbCr // Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16 // U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128 // V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128 // We use 16bit fixed point operations for RGB->YUV conversion (YUV_FIX). // // For the Y'CbCr to RGB conversion, the BT.601 specification reads: // R = 1.164 * (Y-16) + 1.596 * (V-128) // G = 1.164 * (Y-16) - 0.813 * (V-128) - 0.391 * (U-128) // B = 1.164 * (Y-16) + 2.018 * (U-128) // where Y is in the [16,235] range, and U/V in the [16,240] range. // In the table-lookup version (WEBP_YUV_USE_TABLE), the common factor // "1.164 * (Y-16)" can be handled as an offset in the VP8kClip[] table. // So in this case the formulae should read: // R = 1.164 * [Y + 1.371 * (V-128) ] - 18.624 // G = 1.164 * [Y - 0.698 * (V-128) - 0.336 * (U-128)] - 18.624 // B = 1.164 * [Y + 1.733 * (U-128)] - 18.624 // once factorized. // For YUV->RGB conversion, only 14bit fixed precision is used (YUV_FIX2). // That's the maximum possible for a convenient ARM implementation. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_DSP_YUV_H_ #define WEBP_DSP_YUV_H_ #include "./dsp.h" #include "../dec/decode_vp8.h" // Define the following to use the LUT-based code: // #define WEBP_YUV_USE_TABLE #if defined(WEBP_EXPERIMENTAL_FEATURES) // Do NOT activate this feature for real compression. This is only experimental! // This flag is for comparison purpose against JPEG's "YUVj" natural colorspace. // This colorspace is close to Rec.601's Y'CbCr model with the notable // difference of allowing larger range for luma/chroma. // See http://en.wikipedia.org/wiki/YCbCr#JPEG_conversion paragraph, and its // difference with http://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion // #define USE_YUVj #endif //------------------------------------------------------------------------------ // YUV -> RGB conversion #ifdef __cplusplus extern "C" { #endif enum { YUV_FIX = 16, // fixed-point precision for RGB->YUV YUV_HALF = 1 << (YUV_FIX - 1), YUV_MASK = (256 << YUV_FIX) - 1, YUV_RANGE_MIN = -227, // min value of r/g/b output YUV_RANGE_MAX = 256 + 226, // max value of r/g/b output YUV_FIX2 = 14, // fixed-point precision for YUV->RGB YUV_HALF2 = 1 << (YUV_FIX2 - 1), YUV_MASK2 = (256 << YUV_FIX2) - 1 }; // These constants are 14b fixed-point version of ITU-R BT.601 constants. #define kYScale 19077 // 1.164 = 255 / 219 #define kVToR 26149 // 1.596 = 255 / 112 * 0.701 #define kUToG 6419 // 0.391 = 255 / 112 * 0.886 * 0.114 / 0.587 #define kVToG 13320 // 0.813 = 255 / 112 * 0.701 * 0.299 / 0.587 #define kUToB 33050 // 2.018 = 255 / 112 * 0.886 #define kRCst (-kYScale * 16 - kVToR * 128 + YUV_HALF2) #define kGCst (-kYScale * 16 + kUToG * 128 + kVToG * 128 + YUV_HALF2) #define kBCst (-kYScale * 16 - kUToB * 128 + YUV_HALF2) //------------------------------------------------------------------------------ #if !defined(WEBP_YUV_USE_TABLE) // slower on x86 by ~7-8%, but bit-exact with the SSE2 version static WEBP_INLINE int VP8Clip8(int v) { return ((v & ~YUV_MASK2) == 0) ? (v >> YUV_FIX2) : (v < 0) ? 0 : 255; } static WEBP_INLINE int VP8YUVToR(int y, int v) { return VP8Clip8(kYScale * y + kVToR * v + kRCst); } static WEBP_INLINE int VP8YUVToG(int y, int u, int v) { return VP8Clip8(kYScale * y - kUToG * u - kVToG * v + kGCst); } static WEBP_INLINE int VP8YUVToB(int y, int u) { return VP8Clip8(kYScale * y + kUToB * u + kBCst); } static WEBP_INLINE void VP8YuvToRgb(int y, int u, int v, uint8_t* const rgb) { rgb[0] = VP8YUVToR(y, v); rgb[1] = VP8YUVToG(y, u, v); rgb[2] = VP8YUVToB(y, u); } static WEBP_INLINE void VP8YuvToBgr(int y, int u, int v, uint8_t* const bgr) { bgr[0] = VP8YUVToB(y, u); bgr[1] = VP8YUVToG(y, u, v); bgr[2] = VP8YUVToR(y, v); } static WEBP_INLINE void VP8YuvToRgb565(int y, int u, int v, uint8_t* const rgb) { const int r = VP8YUVToR(y, v); // 5 usable bits const int g = VP8YUVToG(y, u, v); // 6 usable bits const int b = VP8YUVToB(y, u); // 5 usable bits const int rg = (r & 0xf8) | (g >> 5); const int gb = ((g << 3) & 0xe0) | (b >> 3); #ifdef WEBP_SWAP_16BIT_CSP rgb[0] = gb; rgb[1] = rg; #else rgb[0] = rg; rgb[1] = gb; #endif } static WEBP_INLINE void VP8YuvToRgba4444(int y, int u, int v, uint8_t* const argb) { const int r = VP8YUVToR(y, v); // 4 usable bits const int g = VP8YUVToG(y, u, v); // 4 usable bits const int b = VP8YUVToB(y, u); // 4 usable bits const int rg = (r & 0xf0) | (g >> 4); const int ba = (b & 0xf0) | 0x0f; // overwrite the lower 4 bits #ifdef WEBP_SWAP_16BIT_CSP argb[0] = ba; argb[1] = rg; #else argb[0] = rg; argb[1] = ba; #endif } #else // Table-based version, not totally equivalent to the SSE2 version. // Rounding diff is only +/-1 though. extern int16_t VP8kVToR[256], VP8kUToB[256]; extern int32_t VP8kVToG[256], VP8kUToG[256]; extern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN]; extern uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN]; static WEBP_INLINE void VP8YuvToRgb(int y, int u, int v, uint8_t* const rgb) { const int r_off = VP8kVToR[v]; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int b_off = VP8kUToB[u]; rgb[0] = VP8kClip[y + r_off - YUV_RANGE_MIN]; rgb[1] = VP8kClip[y + g_off - YUV_RANGE_MIN]; rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN]; } static WEBP_INLINE void VP8YuvToBgr(int y, int u, int v, uint8_t* const bgr) { const int r_off = VP8kVToR[v]; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int b_off = VP8kUToB[u]; bgr[0] = VP8kClip[y + b_off - YUV_RANGE_MIN]; bgr[1] = VP8kClip[y + g_off - YUV_RANGE_MIN]; bgr[2] = VP8kClip[y + r_off - YUV_RANGE_MIN]; } static WEBP_INLINE void VP8YuvToRgb565(int y, int u, int v, uint8_t* const rgb) { const int r_off = VP8kVToR[v]; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int b_off = VP8kUToB[u]; const int rg = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) | (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5)); const int gb = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) | (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3)); #ifdef WEBP_SWAP_16BIT_CSP rgb[0] = gb; rgb[1] = rg; #else rgb[0] = rg; rgb[1] = gb; #endif } static WEBP_INLINE void VP8YuvToRgba4444(int y, int u, int v, uint8_t* const argb) { const int r_off = VP8kVToR[v]; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int b_off = VP8kUToB[u]; const int rg = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) | VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]); const int ba = (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4) | 0x0f; #ifdef WEBP_SWAP_16BIT_CSP argb[0] = ba; argb[1] = rg; #else argb[0] = rg; argb[1] = ba; #endif } #endif // WEBP_YUV_USE_TABLE //----------------------------------------------------------------------------- // Alpha handling variants static WEBP_INLINE void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v, uint8_t* const argb) { argb[0] = 0xff; VP8YuvToRgb(y, u, v, argb + 1); } static WEBP_INLINE void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v, uint8_t* const bgra) { VP8YuvToBgr(y, u, v, bgra); bgra[3] = 0xff; } static WEBP_INLINE void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v, uint8_t* const rgba) { VP8YuvToRgb(y, u, v, rgba); rgba[3] = 0xff; } // Must be called before everything, to initialize the tables. void VP8YUVInit(void); //----------------------------------------------------------------------------- // SSE2 extra functions (mostly for upsampling_sse2.c) #if defined(WEBP_USE_SSE2) #if defined(FANCY_UPSAMPLING) // Process 32 pixels and store the result (24b or 32b per pixel) in *dst. void VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst); void VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst); void VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst); void VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v, uint8_t* dst); #endif // FANCY_UPSAMPLING // Must be called to initialize tables before using the functions. void VP8YUVInitSSE2(void); #endif // WEBP_USE_SSE2 //------------------------------------------------------------------------------ // RGB -> YUV conversion // Stub functions that can be called with various rounding values: static WEBP_INLINE int VP8ClipUV(int uv, int rounding) { uv = (uv + rounding + (128 << (YUV_FIX + 2))) >> (YUV_FIX + 2); return ((uv & ~0xff) == 0) ? uv : (uv < 0) ? 0 : 255; } #ifndef USE_YUVj static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) { const int luma = 16839 * r + 33059 * g + 6420 * b; return (luma + rounding + (16 << YUV_FIX)) >> YUV_FIX; // no need to clip } static WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) { const int u = -9719 * r - 19081 * g + 28800 * b; return VP8ClipUV(u, rounding); } static WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) { const int v = +28800 * r - 24116 * g - 4684 * b; return VP8ClipUV(v, rounding); } #else // This JPEG-YUV colorspace, only for comparison! // These are also 16bit precision coefficients from Rec.601, but with full // [0..255] output range. static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) { const int luma = 19595 * r + 38470 * g + 7471 * b; return (luma + rounding) >> YUV_FIX; // no need to clip } static WEBP_INLINE int VP8_RGB_TO_U(int r, int g, int b, int rounding) { const int u = -11058 * r - 21710 * g + 32768 * b; return VP8ClipUV(u, rounding); } static WEBP_INLINE int VP8_RGB_TO_V(int r, int g, int b, int rounding) { const int v = 32768 * r - 27439 * g - 5329 * b; return VP8ClipUV(v, rounding); } #endif // USE_YUVj #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_DSP_YUV_H_ */ libwebp-0.4.0/src/dsp/cpu.c0000644000014400001440000000470012255002107012352 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // CPU detection // // Author: Christian Duvivier (cduvivier@google.com) #include "./dsp.h" #if defined(__ANDROID__) #include #endif //------------------------------------------------------------------------------ // SSE2 detection. // // apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC. #if (defined(__pic__) || defined(__PIC__)) && defined(__i386__) static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) { __asm__ volatile ( "mov %%ebx, %%edi\n" "cpuid\n" "xchg %%edi, %%ebx\n" : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) : "a"(info_type)); } #elif defined(__i386__) || defined(__x86_64__) static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) { __asm__ volatile ( "cpuid\n" : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) : "a"(info_type)); } #elif defined(WEBP_MSC_SSE2) #define GetCPUInfo __cpuid #endif #if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2) static int x86CPUInfo(CPUFeature feature) { int cpu_info[4]; GetCPUInfo(cpu_info, 1); if (feature == kSSE2) { return 0 != (cpu_info[3] & 0x04000000); } if (feature == kSSE3) { return 0 != (cpu_info[2] & 0x00000001); } return 0; } VP8CPUInfo VP8GetCPUInfo = x86CPUInfo; #elif defined(WEBP_ANDROID_NEON) static int AndroidCPUInfo(CPUFeature feature) { const AndroidCpuFamily cpu_family = android_getCpuFamily(); const uint64_t cpu_features = android_getCpuFeatures(); if (feature == kNEON) { return (cpu_family == ANDROID_CPU_FAMILY_ARM && 0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)); } return 0; } VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo; #elif defined(__ARM_NEON__) // define a dummy function to enable turning off NEON at runtime by setting // VP8DecGetCPUInfo = NULL static int armCPUInfo(CPUFeature feature) { (void)feature; return 1; } VP8CPUInfo VP8GetCPUInfo = armCPUInfo; #else VP8CPUInfo VP8GetCPUInfo = NULL; #endif libwebp-0.4.0/src/dsp/Makefile.am0000644000014400001440000000211612255002107013452 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libwebpdsp.la if BUILD_LIBWEBPDECODER noinst_LTLIBRARIES += libwebpdspdecode.la endif common_HEADERS = ../webp/types.h commondir = $(includedir)/webp COMMON_SOURCES = COMMON_SOURCES += cpu.c COMMON_SOURCES += dec.c COMMON_SOURCES += dec_neon.c COMMON_SOURCES += dec_sse2.c COMMON_SOURCES += dsp.h COMMON_SOURCES += lossless.c COMMON_SOURCES += lossless.h COMMON_SOURCES += upsampling.c COMMON_SOURCES += upsampling_neon.c COMMON_SOURCES += upsampling_sse2.c COMMON_SOURCES += yuv.c COMMON_SOURCES += yuv.h ENC_SOURCES = ENC_SOURCES += enc.c ENC_SOURCES += enc_neon.c ENC_SOURCES += enc_sse2.c libwebpdsp_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) noinst_HEADERS = noinst_HEADERS += ../dec/decode_vp8.h noinst_HEADERS += ../webp/decode.h libwebpdsp_la_LDFLAGS = -lm libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) $(USE_SWAP_16BIT_CSP) if BUILD_LIBWEBPDECODER libwebpdspdecode_la_SOURCES = $(COMMON_SOURCES) libwebpdspdecode_la_LDFLAGS = $(libwebpdsp_la_LDFLAGS) libwebpdspdecode_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) endif libwebp-0.4.0/src/webp/0000755000014400001440000000000012255002107011565 5ustar libwebp-0.4.0/src/webp/mux_types.h0000644000014400001440000000611512255002107013776 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Data-types common to the mux and demux libraries. // // Author: Urvang (urvang@google.com) #ifndef WEBP_WEBP_MUX_TYPES_H_ #define WEBP_WEBP_MUX_TYPES_H_ #include // free() #include // memset() #include "./types.h" #ifdef __cplusplus extern "C" { #endif // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPFeatureFlags WebPFeatureFlags; // typedef enum WebPMuxAnimDispose WebPMuxAnimDispose; // typedef enum WebPMuxAnimBlend WebPMuxAnimBlend; typedef struct WebPData WebPData; // VP8X Feature Flags. typedef enum WebPFeatureFlags { FRAGMENTS_FLAG = 0x00000001, ANIMATION_FLAG = 0x00000002, XMP_FLAG = 0x00000004, EXIF_FLAG = 0x00000008, ALPHA_FLAG = 0x00000010, ICCP_FLAG = 0x00000020 } WebPFeatureFlags; // Dispose method (animation only). Indicates how the area used by the current // frame is to be treated before rendering the next frame on the canvas. typedef enum WebPMuxAnimDispose { WEBP_MUX_DISPOSE_NONE, // Do not dispose. WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color. } WebPMuxAnimDispose; // Blend operation (animation only). Indicates how transparent pixels of the // current frame are blended with those of the previous canvas. typedef enum WebPMuxAnimBlend { WEBP_MUX_BLEND, // Blend. WEBP_MUX_NO_BLEND // Do not blend. } WebPMuxAnimBlend; // Data type used to describe 'raw' data, e.g., chunk data // (ICC profile, metadata) and WebP compressed image data. struct WebPData { const uint8_t* bytes; size_t size; }; // Initializes the contents of the 'webp_data' object with default values. static WEBP_INLINE void WebPDataInit(WebPData* webp_data) { if (webp_data != NULL) { memset(webp_data, 0, sizeof(*webp_data)); } } // Clears the contents of the 'webp_data' object by calling free(). Does not // deallocate the object itself. static WEBP_INLINE void WebPDataClear(WebPData* webp_data) { if (webp_data != NULL) { free((void*)webp_data->bytes); WebPDataInit(webp_data); } } // Allocates necessary storage for 'dst' and copies the contents of 'src'. // Returns true on success. static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) { if (src == NULL || dst == NULL) return 0; WebPDataInit(dst); if (src->bytes != NULL && src->size != 0) { dst->bytes = (uint8_t*)malloc(src->size); if (dst->bytes == NULL) return 0; memcpy((void*)dst->bytes, src->bytes, src->size); dst->size = src->size; } return 1; } #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_MUX_TYPES_H_ */ libwebp-0.4.0/src/webp/demux.h0000644000014400001440000002271412255002107013066 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Demux API. // Enables extraction of image and extended format data from WebP files. // Code Example: Demuxing WebP data to extract all the frames, ICC profile // and EXIF/XMP metadata. /* WebPDemuxer* demux = WebPDemux(&webp_data); uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); // ... (Get information about the features present in the WebP file). uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); // ... (Iterate over all frames). WebPIterator iter; if (WebPDemuxGetFrame(demux, 1, &iter)) { do { // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), // ... and get other frame properties like width, height, offsets etc. // ... see 'struct WebPIterator' below for more info). } while (WebPDemuxNextFrame(&iter)); WebPDemuxReleaseIterator(&iter); } // ... (Extract metadata). WebPChunkIterator chunk_iter; if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); // ... (Consume the ICC profile in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); // ... (Consume the XMP metadata in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); WebPDemuxDelete(demux); */ #ifndef WEBP_WEBP_DEMUX_H_ #define WEBP_WEBP_DEMUX_H_ #include "./mux_types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_DEMUX_ABI_VERSION 0x0101 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPDemuxState WebPDemuxState; // typedef enum WebPFormatFeature WebPFormatFeature; typedef struct WebPDemuxer WebPDemuxer; typedef struct WebPIterator WebPIterator; typedef struct WebPChunkIterator WebPChunkIterator; //------------------------------------------------------------------------------ // Returns the version number of the demux library, packed in hexadecimal using // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN(int) WebPGetDemuxVersion(void); //------------------------------------------------------------------------------ // Life of a Demux object typedef enum WebPDemuxState { WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing. WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header. WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete, // data may be available. WEBP_DEMUX_DONE = 2 // Entire file has been parsed. } WebPDemuxState; // Internal, version-checked, entry point WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal( const WebPData*, int, WebPDemuxState*, int); // Parses the full WebP file given by 'data'. // Returns a WebPDemuxer object on successful parse, NULL otherwise. static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); } // Parses the possibly incomplete WebP file given by 'data'. // If 'state' is non-NULL it will be set to indicate the status of the demuxer. // Returns NULL in case of error or if there isn't enough data to start parsing; // and a WebPDemuxer object on successful parse. // Note that WebPDemuxer keeps internal pointers to 'data' memory segment. // If this data is volatile, the demuxer object should be deleted (by calling // WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data. // This is usually an inexpensive operation. static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( const WebPData* data, WebPDemuxState* state) { return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); } // Frees memory associated with 'dmux'. WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux); //------------------------------------------------------------------------------ // Data/information extraction. typedef enum WebPFormatFeature { WEBP_FF_FORMAT_FLAGS, // Extended format flags present in the 'VP8X' chunk. WEBP_FF_CANVAS_WIDTH, WEBP_FF_CANVAS_HEIGHT, WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, WEBP_FF_FRAME_COUNT // Number of frames present in the demux object. // In case of a partial demux, this is the number of // frames seen so far, with the last frame possibly // being partial. } WebPFormatFeature; // Get the 'feature' value from the 'dmux'. // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() // returned a state > WEBP_DEMUX_PARSING_HEADER. WEBP_EXTERN(uint32_t) WebPDemuxGetI( const WebPDemuxer* dmux, WebPFormatFeature feature); //------------------------------------------------------------------------------ // Frame iteration. struct WebPIterator { int frame_num; int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. int fragment_num; int num_fragments; int x_offset, y_offset; // offset relative to the canvas. int width, height; // dimensions of this frame or fragment. int duration; // display duration in milliseconds. WebPMuxAnimDispose dispose_method; // dispose method for the frame. int complete; // true if 'fragment' contains a full frame. partial images // may still be decoded with the WebP incremental decoder. WebPData fragment; // The frame or fragment given by 'frame_num' and // 'fragment_num'. int has_alpha; // True if the frame or fragment contains transparency. WebPMuxAnimBlend blend_method; // Blend operation for the frame. uint32_t pad[2]; // padding for later use. void* private_; // for internal use only. }; // Retrieves frame 'frame_number' from 'dmux'. // 'iter->fragment' points to the first fragment on return from this function. // Individual fragments may be extracted using WebPDemuxSelectFragment(). // Setting 'frame_number' equal to 0 will return the last frame of the image. // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. // Call WebPDemuxReleaseIterator() when use of the iterator is complete. // NOTE: 'dmux' must persist for the lifetime of 'iter'. WEBP_EXTERN(int) WebPDemuxGetFrame( const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or // previous ('iter->frame_num' - 1) frame. These functions do not loop. // Returns true on success, false otherwise. WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter); WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter); // Sets 'iter->fragment' to reflect fragment number 'fragment_num'. // Returns true if fragment 'fragment_num' is present, false otherwise. WEBP_EXTERN(int) WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num); // Releases any memory associated with 'iter'. // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same // iter. Also, must be called before destroying the associated WebPDemuxer with // WebPDemuxDelete(). WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter); //------------------------------------------------------------------------------ // Chunk iteration. struct WebPChunkIterator { // The current and total number of chunks with the fourcc given to // WebPDemuxGetChunk(). int chunk_num; int num_chunks; WebPData chunk; // The payload of the chunk. uint32_t pad[6]; // padding for later use void* private_; }; // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from // 'dmux'. // 'fourcc' is a character array containing the fourcc of the chunk to return, // e.g., "ICCP", "XMP ", "EXIF", etc. // Setting 'chunk_number' equal to 0 will return the last chunk in a set. // Returns true if the chunk is found, false otherwise. Image related chunk // payloads are accessed through WebPDemuxGetFrame() and related functions. // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. // NOTE: 'dmux' must persist for the lifetime of the iterator. WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux, const char fourcc[4], int chunk_number, WebPChunkIterator* iter); // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous // ('iter->chunk_num' - 1) chunk. These functions do not loop. // Returns true on success, false otherwise. WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter); WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter); // Releases any memory associated with 'iter'. // Must be called before destroying the associated WebPDemuxer with // WebPDemuxDelete(). WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_DEMUX_H_ */ libwebp-0.4.0/src/webp/mux.h0000644000014400001440000003707312255002107012561 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // RIFF container manipulation for WebP images. // // Authors: Urvang (urvang@google.com) // Vikas (vikasa@google.com) // This API allows manipulation of WebP container images containing features // like color profile, metadata, animation and fragmented images. // // Code Example#1: Create a WebPMux object with image data, color profile and // XMP metadata. /* int copy_data = 0; WebPMux* mux = WebPMuxNew(); // ... (Prepare image data). WebPMuxSetImage(mux, &image, copy_data); // ... (Prepare ICCP color profile data). WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); // ... (Prepare XMP metadata). WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data); // Get data from mux in WebP RIFF format. WebPMuxAssemble(mux, &output_data); WebPMuxDelete(mux); // ... (Consume output_data; e.g. write output_data.bytes to file). WebPDataClear(&output_data); */ // Code Example#2: Get image and color profile data from a WebP file. /* int copy_data = 0; // ... (Read data from file). WebPMux* mux = WebPMuxCreate(&data, copy_data); WebPMuxGetFrame(mux, 1, &image); // ... (Consume image; e.g. call WebPDecode() to decode the data). WebPMuxGetChunk(mux, "ICCP", &icc_profile); // ... (Consume icc_data). WebPMuxDelete(mux); free(data); */ #ifndef WEBP_WEBP_MUX_H_ #define WEBP_WEBP_MUX_H_ #include "./mux_types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_MUX_ABI_VERSION 0x0101 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPMuxError WebPMuxError; // typedef enum WebPChunkId WebPChunkId; typedef struct WebPMux WebPMux; // main opaque object. typedef struct WebPMuxFrameInfo WebPMuxFrameInfo; typedef struct WebPMuxAnimParams WebPMuxAnimParams; // Error codes typedef enum WebPMuxError { WEBP_MUX_OK = 1, WEBP_MUX_NOT_FOUND = 0, WEBP_MUX_INVALID_ARGUMENT = -1, WEBP_MUX_BAD_DATA = -2, WEBP_MUX_MEMORY_ERROR = -3, WEBP_MUX_NOT_ENOUGH_DATA = -4 } WebPMuxError; // IDs for different types of chunks. typedef enum WebPChunkId { WEBP_CHUNK_VP8X, // VP8X WEBP_CHUNK_ICCP, // ICCP WEBP_CHUNK_ANIM, // ANIM WEBP_CHUNK_ANMF, // ANMF WEBP_CHUNK_FRGM, // FRGM WEBP_CHUNK_ALPHA, // ALPH WEBP_CHUNK_IMAGE, // VP8/VP8L WEBP_CHUNK_EXIF, // EXIF WEBP_CHUNK_XMP, // XMP WEBP_CHUNK_UNKNOWN, // Other chunks. WEBP_CHUNK_NIL } WebPChunkId; //------------------------------------------------------------------------------ // Returns the version number of the mux library, packed in hexadecimal using // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN(int) WebPGetMuxVersion(void); //------------------------------------------------------------------------------ // Life of a Mux object // Internal, version-checked, entry point WEBP_EXTERN(WebPMux*) WebPNewInternal(int); // Creates an empty mux object. // Returns: // A pointer to the newly created empty mux object. static WEBP_INLINE WebPMux* WebPMuxNew(void) { return WebPNewInternal(WEBP_MUX_ABI_VERSION); } // Deletes the mux object. // Parameters: // mux - (in/out) object to be deleted WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux); //------------------------------------------------------------------------------ // Mux creation. // Internal, version-checked, entry point WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int); // Creates a mux object from raw data given in WebP RIFF format. // Parameters: // bitstream - (in) the bitstream data in WebP RIFF format // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // A pointer to the mux object created from given data - on success. // NULL - In case of invalid data or memory error. static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream, int copy_data) { return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION); } //------------------------------------------------------------------------------ // Non-image chunks. // Note: Only non-image related chunks should be managed through chunk APIs. // (Image related chunks are: "ANMF", "FRGM", "VP8 ", "VP8L" and "ALPH"). // To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(), // WebPMuxGetFrame() and WebPMuxDeleteFrame(). // Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object. // Any existing chunk(s) with the same id will be removed. // Parameters: // mux - (in/out) object to which the chunk is to be added // fourcc - (in) a character array containing the fourcc of the given chunk; // e.g., "ICCP", "XMP ", "EXIF" etc. // chunk_data - (in) the chunk data to be added // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL // or if fourcc corresponds to an image chunk. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk( WebPMux* mux, const char fourcc[4], const WebPData* chunk_data, int copy_data); // Gets a reference to the data of the chunk with id 'fourcc' in the mux object. // The caller should NOT free the returned data. // Parameters: // mux - (in) object from which the chunk data is to be fetched // fourcc - (in) a character array containing the fourcc of the chunk; // e.g., "ICCP", "XMP ", "EXIF" etc. // chunk_data - (out) returned chunk data // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL // or if fourcc corresponds to an image chunk. // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk( const WebPMux* mux, const char fourcc[4], WebPData* chunk_data); // Deletes the chunk with the given 'fourcc' from the mux object. // Parameters: // mux - (in/out) object from which the chunk is to be deleted // fourcc - (in) a character array containing the fourcc of the chunk; // e.g., "ICCP", "XMP ", "EXIF" etc. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL // or if fourcc corresponds to an image chunk. // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxDeleteChunk( WebPMux* mux, const char fourcc[4]); //------------------------------------------------------------------------------ // Images. // Encapsulates data about a single frame/fragment. struct WebPMuxFrameInfo { WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream // or a single-image WebP file. int x_offset; // x-offset of the frame. int y_offset; // y-offset of the frame. int duration; // duration of the frame (in milliseconds). WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF, // WEBP_CHUNK_FRGM or WEBP_CHUNK_IMAGE WebPMuxAnimDispose dispose_method; // Disposal method for the frame. WebPMuxAnimBlend blend_method; // Blend operation for the frame. uint32_t pad[1]; // padding for later use }; // Sets the (non-animated and non-fragmented) image in the mux object. // Note: Any existing images (including frames/fragments) will be removed. // Parameters: // mux - (in/out) object in which the image is to be set // bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image // WebP file (non-animated and non-fragmented) // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxSetImage( WebPMux* mux, const WebPData* bitstream, int copy_data); // Adds a frame at the end of the mux object. // Notes: (1) frame.id should be one of WEBP_CHUNK_ANMF or WEBP_CHUNK_FRGM // (2) For setting a non-animated non-fragmented image, use // WebPMuxSetImage() instead. // (3) Type of frame being pushed must be same as the frames in mux. // (4) As WebP only supports even offsets, any odd offset will be snapped // to an even location using: offset &= ~1 // Parameters: // mux - (in/out) object to which the frame is to be added // frame - (in) frame data. // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL // or if content of 'frame' is invalid. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame( WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data); // Gets the nth frame from the mux object. // The content of 'frame->bitstream' is allocated using malloc(), and NOT // owned by the 'mux' object. It MUST be deallocated by the caller by calling // WebPDataClear(). // nth=0 has a special meaning - last position. // Parameters: // mux - (in) object from which the info is to be fetched // nth - (in) index of the frame in the mux object // frame - (out) data of the returned frame // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL. // WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. // WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame( const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame); // Deletes a frame from the mux object. // nth=0 has a special meaning - last position. // Parameters: // mux - (in/out) object from which a frame is to be deleted // nth - (in) The position from which the frame is to be deleted // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL. // WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object // before deletion. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth); //------------------------------------------------------------------------------ // Animation. // Animation parameters. struct WebPMuxAnimParams { uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as: // Bits 00 to 07: Alpha. // Bits 08 to 15: Red. // Bits 16 to 23: Green. // Bits 24 to 31: Blue. int loop_count; // Number of times to repeat the animation [0 = infinite]. }; // Sets the animation parameters in the mux object. Any existing ANIM chunks // will be removed. // Parameters: // mux - (in/out) object in which ANIM chunk is to be set/added // params - (in) animation parameters. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxSetAnimationParams( WebPMux* mux, const WebPMuxAnimParams* params); // Gets the animation parameters from the mux object. // Parameters: // mux - (in) object from which the animation parameters to be fetched // params - (out) animation parameters extracted from the ANIM chunk // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. // WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams( const WebPMux* mux, WebPMuxAnimParams* params); //------------------------------------------------------------------------------ // Misc Utilities. // Gets the canvas size from the mux object. // Note: This method assumes that the VP8X chunk, if present, is up-to-date. // That is, the mux object hasn't been modified since the last call to // WebPMuxAssemble() or WebPMuxCreate(). // Parameters: // mux - (in) object from which the canvas size is to be fetched // width - (out) canvas width // height - (out) canvas height // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL. // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxGetCanvasSize(const WebPMux* mux, int* width, int* height); // Gets the feature flags from the mux object. // Note: This method assumes that the VP8X chunk, if present, is up-to-date. // That is, the mux object hasn't been modified since the last call to // WebPMuxAssemble() or WebPMuxCreate(). // Parameters: // mux - (in) object from which the features are to be fetched // flags - (out) the flags specifying which features are present in the // mux object. This will be an OR of various flag values. // Enum 'WebPFeatureFlags' can be used to test individual flag values. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL. // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags); // Gets number of chunks with the given 'id' in the mux object. // Parameters: // mux - (in) object from which the info is to be fetched // id - (in) chunk id specifying the type of chunk // num_elements - (out) number of chunks with the given chunk id // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux, WebPChunkId id, int* num_elements); // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. // This function also validates the mux object. // Note: The content of 'assembled_data' will be ignored and overwritten. // Also, the content of 'assembled_data' is allocated using malloc(), and NOT // owned by the 'mux' object. It MUST be deallocated by the caller by calling // WebPDataClear(). // Parameters: // mux - (in/out) object whose chunks are to be assembled // assembled_data - (out) assembled WebP data // Returns: // WEBP_MUX_BAD_DATA - if mux object is invalid. // WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_MUX_H_ */ libwebp-0.4.0/src/webp/decode.h0000644000014400001440000005426712255002107013177 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Main decoding functions for WebP images. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_DECODE_H_ #define WEBP_WEBP_DECODE_H_ #include "./types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_DECODER_ABI_VERSION 0x0203 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum VP8StatusCode VP8StatusCode; // typedef enum WEBP_CSP_MODE WEBP_CSP_MODE; typedef struct WebPRGBABuffer WebPRGBABuffer; typedef struct WebPYUVABuffer WebPYUVABuffer; typedef struct WebPDecBuffer WebPDecBuffer; typedef struct WebPIDecoder WebPIDecoder; typedef struct WebPBitstreamFeatures WebPBitstreamFeatures; typedef struct WebPDecoderOptions WebPDecoderOptions; typedef struct WebPDecoderConfig WebPDecoderConfig; // Return the decoder's version number, packed in hexadecimal using 8bits for // each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN(int) WebPGetDecoderVersion(void); // Retrieve basic header information: width, height. // This function will also validate the header and return 0 in // case of formatting error. // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant. WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); // Decodes WebP images pointed to by 'data' and returns RGBA samples, along // with the dimensions in *width and *height. The ordering of samples in // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). // The returned pointer should be deleted calling free(). // Returns NULL in case of error. WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. // If the bitstream contains transparency, it is ignored. WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size, int* width, int* height); // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer // returned is the Y samples buffer. Upon return, *u and *v will point to // the U and V chroma data. These U and V buffers need NOT be free()'d, // unlike the returned Y luma one. The dimension of the U and V planes // are both (*width + 1) / 2 and (*height + 1)/ 2. // Upon return, the Y buffer has a stride returned as '*stride', while U and V // have a common stride returned as '*uv_stride'. // Return NULL in case of error. // (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size, int* width, int* height, uint8_t** u, uint8_t** v, int* stride, int* uv_stride); // These five functions are variants of the above ones, that decode the image // directly into a pre-allocated buffer 'output_buffer'. The maximum storage // available in this buffer is indicated by 'output_buffer_size'. If this // storage is not sufficient (or an error occurred), NULL is returned. // Otherwise, output_buffer is returned, for convenience. // The parameter 'output_stride' specifies the distance (in bytes) // between scanlines. Hence, output_buffer_size is expected to be at least // output_stride x picture-height. WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); // RGB and BGR variants. Here too the transparency information, if present, // will be dropped and ignored. WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly // into pre-allocated luma/chroma plane buffers. This function requires the // strides to be passed: one for the luma plane and one for each of the // chroma ones. The size of each plane buffer is passed as 'luma_size', // 'u_size' and 'v_size' respectively. // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred // during decoding (or because some buffers were found to be too small). WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto( const uint8_t* data, size_t data_size, uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride); //------------------------------------------------------------------------------ // Output colorspaces and buffer // Colorspaces // Note: the naming describes the byte-ordering of packed samples in memory. // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for // these two modes: // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... typedef enum WEBP_CSP_MODE { MODE_RGB = 0, MODE_RGBA = 1, MODE_BGR = 2, MODE_BGRA = 3, MODE_ARGB = 4, MODE_RGBA_4444 = 5, MODE_RGB_565 = 6, // RGB-premultiplied transparent modes (alpha value is preserved) MODE_rgbA = 7, MODE_bgrA = 8, MODE_Argb = 9, MODE_rgbA_4444 = 10, // YUV modes must come after RGB ones. MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 MODE_LAST = 13 } WEBP_CSP_MODE; // Some useful macros: static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || mode == MODE_rgbA_4444); } static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || mode == MODE_RGBA_4444 || mode == MODE_YUVA || WebPIsPremultipliedMode(mode)); } static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { return (mode < MODE_YUV); } //------------------------------------------------------------------------------ // WebPDecBuffer: Generic structure for describing the output sample buffer. struct WebPRGBABuffer { // view as RGBA uint8_t* rgba; // pointer to RGBA samples int stride; // stride in bytes from one scanline to the next. size_t size; // total size of the *rgba buffer. }; struct WebPYUVABuffer { // view as YUVA uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples int y_stride; // luma stride int u_stride, v_stride; // chroma strides int a_stride; // alpha stride size_t y_size; // luma plane size size_t u_size, v_size; // chroma planes size size_t a_size; // alpha-plane size }; // Output buffer struct WebPDecBuffer { WEBP_CSP_MODE colorspace; // Colorspace. int width, height; // Dimensions. int is_external_memory; // If true, 'internal_memory' pointer is not used. union { WebPRGBABuffer RGBA; WebPYUVABuffer YUVA; } u; // Nameless union of buffer parameters. uint32_t pad[4]; // padding for later use uint8_t* private_memory; // Internally allocated memory (only when // is_external_memory is false). Should not be used // externally, but accessed via the buffer union. }; // Internal, version-checked, entry point WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int); // Initialize the structure as empty. Must be called before any other use. // Returns false in case of version mismatch static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); } // Free any memory associated with the buffer. Must always be called last. // Note: doesn't free the 'buffer' structure itself. WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer); //------------------------------------------------------------------------------ // Enumeration of the status codes typedef enum VP8StatusCode { VP8_STATUS_OK = 0, VP8_STATUS_OUT_OF_MEMORY, VP8_STATUS_INVALID_PARAM, VP8_STATUS_BITSTREAM_ERROR, VP8_STATUS_UNSUPPORTED_FEATURE, VP8_STATUS_SUSPENDED, VP8_STATUS_USER_ABORT, VP8_STATUS_NOT_ENOUGH_DATA } VP8StatusCode; //------------------------------------------------------------------------------ // Incremental decoding // // This API allows streamlined decoding of partial data. // Picture can be incrementally decoded as data become available thanks to the // WebPIDecoder object. This object can be left in a SUSPENDED state if the // picture is only partially decoded, pending additional input. // Code example: // // WebPInitDecBuffer(&buffer); // buffer.colorspace = mode; // ... // WebPIDecoder* idec = WebPINewDecoder(&buffer); // while (has_more_data) { // // ... (get additional data) // status = WebPIAppend(idec, new_data, new_data_size); // if (status != VP8_STATUS_SUSPENDED || // break; // } // // // The above call decodes the current available buffer. // // Part of the image can now be refreshed by calling to // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. // } // WebPIDelete(idec); // Creates a new incremental decoder with the supplied buffer parameter. // This output_buffer can be passed NULL, in which case a default output buffer // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' // is kept, which means that the lifespan of 'output_buffer' must be larger than // that of the returned WebPIDecoder object. // The supplied 'output_buffer' content MUST NOT be changed between calls to // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is // set to 1. In such a case, it is allowed to modify the pointers, size and // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain // within valid bounds. // All other fields of WebPDecBuffer MUST remain constant between calls. // Returns NULL if the allocation failed. WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer); // This function allocates and initializes an incremental-decoder object, which // will output the RGB/A samples specified by 'csp' into a preallocated // buffer 'output_buffer'. The size of this buffer is at least // 'output_buffer_size' and the stride (distance in bytes between two scanlines) // is specified by 'output_stride'. // Additionally, output_buffer can be passed NULL in which case the output // buffer will be allocated automatically when the decoding starts. The // colorspace 'csp' is taken into account for allocating this buffer. All other // parameters are ignored. // Returns NULL if the allocation failed, or if some parameters are invalid. WEBP_EXTERN(WebPIDecoder*) WebPINewRGB( WEBP_CSP_MODE csp, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); // This function allocates and initializes an incremental-decoder object, which // will output the raw luma/chroma samples into a preallocated planes if // supplied. The luma plane is specified by its pointer 'luma', its size // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer // can be pass NULL in case one is not interested in the transparency plane. // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied. // In this case, the output buffer will be automatically allocated (using // MODE_YUVA) when decoding starts. All parameters are then ignored. // Returns NULL if the allocation failed or if a parameter is invalid. WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA( uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride, uint8_t* a, size_t a_size, int a_stride); // Deprecated version of the above, without the alpha plane. // Kept for backward compatibility. WEBP_EXTERN(WebPIDecoder*) WebPINewYUV( uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride); // Deletes the WebPIDecoder object and associated memory. Must always be called // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec); // Copies and decodes the next available data. Returns VP8_STATUS_OK when // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more // data is expected. Returns error in other cases. WEBP_EXTERN(VP8StatusCode) WebPIAppend( WebPIDecoder* idec, const uint8_t* data, size_t data_size); // A variant of the above function to be used when data buffer contains // partial data from the beginning. In this case data buffer is not copied // to the internal memory. // Note that the value of the 'data' pointer can change between calls to // WebPIUpdate, for instance when the data buffer is resized to fit larger data. WEBP_EXTERN(VP8StatusCode) WebPIUpdate( WebPIDecoder* idec, const uint8_t* data, size_t data_size); // Returns the RGB/A image decoded so far. Returns NULL if output params // are not initialized yet. The RGB/A output type corresponds to the colorspace // specified during call to WebPINewDecoder() or WebPINewRGB(). // *last_y is the index of last decoded row in raster scan order. Some pointers // (*last_y, *width etc.) can be NULL if corresponding information is not // needed. WEBP_EXTERN(uint8_t*) WebPIDecGetRGB( const WebPIDecoder* idec, int* last_y, int* width, int* height, int* stride); // Same as above function to get a YUVA image. Returns pointer to the luma // plane or NULL in case of error. If there is no alpha information // the alpha pointer '*a' will be returned NULL. WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA( const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, uint8_t** a, int* width, int* height, int* stride, int* uv_stride, int* a_stride); // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the // alpha information (if present). Kept for backward compatibility. static WEBP_INLINE uint8_t* WebPIDecGetYUV( const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, int* width, int* height, int* stride, int* uv_stride) { return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, stride, uv_stride, NULL); } // Generic call to retrieve information about the displayable area. // If non NULL, the left/right/width/height pointers are filled with the visible // rectangular area so far. // Returns NULL in case the incremental decoder object is in an invalid state. // Otherwise returns the pointer to the internal representation. This structure // is read-only, tied to WebPIDecoder's lifespan and should not be modified. WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea( const WebPIDecoder* idec, int* left, int* top, int* width, int* height); //------------------------------------------------------------------------------ // Advanced decoding parametrization // // Code sample for using the advanced decoding API /* // A) Init a configuration object WebPDecoderConfig config; CHECK(WebPInitDecoderConfig(&config)); // B) optional: retrieve the bitstream's features. CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); // C) Adjust 'config', if needed config.no_fancy_upsampling = 1; config.output.colorspace = MODE_BGRA; // etc. // Note that you can also make config.output point to an externally // supplied memory buffer, provided it's big enough to store the decoded // picture. Otherwise, config.output will just be used to allocate memory // and store the decoded picture. // D) Decode! CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); // E) Decoded image is now in config.output (and config.output.u.RGBA) // F) Reclaim memory allocated in config's object. It's safe to call // this function even if the memory is external and wasn't allocated // by WebPDecode(). WebPFreeDecBuffer(&config.output); */ // Features gathered from the bitstream struct WebPBitstreamFeatures { int width; // Width in pixels, as read from the bitstream. int height; // Height in pixels, as read from the bitstream. int has_alpha; // True if the bitstream contains an alpha channel. int has_animation; // True if the bitstream is an animation. int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless // Unused for now: int no_incremental_decoding; // if true, using incremental decoding is not // recommended. int rotate; // TODO(later) int uv_sampling; // should be 0 for now. TODO(later) uint32_t pad[2]; // padding for later use }; // Internal, version-checked, entry point WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal( const uint8_t*, size_t, WebPBitstreamFeatures*, int); // Retrieve features from the bitstream. The *features structure is filled // with information gathered from the bitstream. // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the // features from headers. Returns error in other cases. static WEBP_INLINE VP8StatusCode WebPGetFeatures( const uint8_t* data, size_t data_size, WebPBitstreamFeatures* features) { return WebPGetFeaturesInternal(data, data_size, features, WEBP_DECODER_ABI_VERSION); } // Decoding options struct WebPDecoderOptions { int bypass_filtering; // if true, skip the in-loop filtering int no_fancy_upsampling; // if true, use faster pointwise upsampler int use_cropping; // if true, cropping is applied _first_ int crop_left, crop_top; // top-left position for cropping. // Will be snapped to even values. int crop_width, crop_height; // dimension of the cropping area int use_scaling; // if true, scaling is applied _afterward_ int scaled_width, scaled_height; // final resolution int use_threads; // if true, use multi-threaded decoding int dithering_strength; // dithering strength (0=Off, 100=full) // Unused for now: int force_rotation; // forced rotation (to be applied _last_) int no_enhancement; // if true, discard enhancement layer uint32_t pad[5]; // padding for later use }; // Main object storing the configuration for advanced decoding. struct WebPDecoderConfig { WebPBitstreamFeatures input; // Immutable bitstream features (optional) WebPDecBuffer output; // Output buffer (can point to external mem) WebPDecoderOptions options; // Decoding options }; // Internal, version-checked, entry point WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int); // Initialize the configuration as empty. This function must always be // called first, unless WebPGetFeatures() is to be called. // Returns false in case of mismatched version. static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) { return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); } // Instantiate a new incremental decoder object with the requested // configuration. The bitstream can be passed using 'data' and 'data_size' // parameter, in which case the features will be parsed and stored into // config->input. Otherwise, 'data' can be NULL and no parsing will occur. // Note that 'config' can be NULL too, in which case a default configuration // is used. // The return WebPIDecoder object must always be deleted calling WebPIDelete(). // Returns NULL in case of error (and config->status will then reflect // the error condition). WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size, WebPDecoderConfig* config); // Non-incremental version. This version decodes the full data at once, taking // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK // if the decoding was successful). WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size, WebPDecoderConfig* config); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_DECODE_H_ */ libwebp-0.4.0/src/webp/encode.h0000644000014400001440000005761512255002107013211 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // WebP encoder: main interface // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_ENCODE_H_ #define WEBP_WEBP_ENCODE_H_ #include "./types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_ENCODER_ABI_VERSION 0x0202 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPImageHint WebPImageHint; // typedef enum WebPEncCSP WebPEncCSP; // typedef enum WebPPreset WebPPreset; // typedef enum WebPEncodingError WebPEncodingError; typedef struct WebPConfig WebPConfig; typedef struct WebPPicture WebPPicture; // main structure for I/O typedef struct WebPAuxStats WebPAuxStats; typedef struct WebPMemoryWriter WebPMemoryWriter; // Return the encoder's version number, packed in hexadecimal using 8bits for // each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN(int) WebPGetEncoderVersion(void); //------------------------------------------------------------------------------ // One-stop-shop call! No questions asked: // Returns the size of the compressed data (pointed to by *output), or 0 if // an error occurred. The compressed data must be released by the caller // using the call 'free(*output)'. // These functions compress using the lossy format, and the quality_factor // can go from 0 (smaller output, lower quality) to 100 (best quality, // larger output). WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); WEBP_EXTERN(size_t) WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output); WEBP_EXTERN(size_t) WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output); WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output); // These functions are the equivalent of the above, but compressing in a // lossless manner. Files are usually larger than lossy format, but will // not suffer any compression loss. WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, int stride, uint8_t** output); WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, int stride, uint8_t** output); WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output); //------------------------------------------------------------------------------ // Coding parameters // Image characteristics hint for the underlying encoder. typedef enum WebPImageHint { WEBP_HINT_DEFAULT = 0, // default preset. WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). WEBP_HINT_LAST } WebPImageHint; // Compression parameters. struct WebPConfig { int lossless; // Lossless encoding (0=lossy(default), 1=lossless). float quality; // between 0 (smallest file) and 100 (biggest) int method; // quality/speed trade-off (0=fast, 6=slower-better) WebPImageHint image_hint; // Hint for image type (lossless only for now). // Parameters related to lossy compression only: int target_size; // if non-zero, set the desired target size in bytes. // Takes precedence over the 'compression' parameter. float target_PSNR; // if non-zero, specifies the minimal distortion to // try to achieve. Takes precedence over target_size. int segments; // maximum number of segments to use, in [1..4] int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum. int filter_strength; // range: [0 = off .. 100 = strongest] int filter_sharpness; // range: [0 = off .. 7 = least sharp] int filter_type; // filtering type: 0 = simple, 1 = strong (only used // if filter_strength > 0 or autofilter > 0) int autofilter; // Auto adjust filter's strength [0 = off, 1 = on] int alpha_compression; // Algorithm for encoding the alpha plane (0 = none, // 1 = compressed with WebP lossless). Default is 1. int alpha_filtering; // Predictive filtering method for alpha plane. // 0: none, 1: fast, 2: best. Default if 1. int alpha_quality; // Between 0 (smallest size) and 100 (lossless). // Default is 100. int pass; // number of entropy-analysis passes (in [1..10]). int show_compressed; // if true, export the compressed picture back. // In-loop filtering is not applied. int preprocessing; // preprocessing filter: // 0=none, 1=segment-smooth, 2=pseudo-random dithering int partitions; // log2(number of token partitions) in [0..3]. Default // is set to 0 for easier progressive decoding. int partition_limit; // quality degradation allowed to fit the 512k limit // on prediction modes coding (0: no degradation, // 100: maximum possible degradation). int emulate_jpeg_size; // If true, compression parameters will be remapped // to better match the expected output size from // JPEG compression. Generally, the output size will // be similar but the degradation will be lower. int thread_level; // If non-zero, try and use multi-threaded encoding. int low_memory; // If set, reduce memory usage (but increase CPU use). uint32_t pad[5]; // padding for later use }; // Enumerate some predefined settings for WebPConfig, depending on the type // of source picture. These presets are used when calling WebPConfigPreset(). typedef enum WebPPreset { WEBP_PRESET_DEFAULT = 0, // default preset. WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details WEBP_PRESET_ICON, // small-sized colorful images WEBP_PRESET_TEXT // text-like } WebPPreset; // Internal, version-checked, entry point WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int); // Should always be called, to initialize a fresh WebPConfig structure before // modification. Returns false in case of version mismatch. WebPConfigInit() // must have succeeded before using the 'config' object. // Note that the default values are lossless=0 and quality=75. static WEBP_INLINE int WebPConfigInit(WebPConfig* config) { return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f, WEBP_ENCODER_ABI_VERSION); } // This function will initialize the configuration according to a predefined // set of parameters (referred to by 'preset') and a given quality factor. // This function can be called as a replacement to WebPConfigInit(). Will // return false in case of error. static WEBP_INLINE int WebPConfigPreset(WebPConfig* config, WebPPreset preset, float quality) { return WebPConfigInitInternal(config, preset, quality, WEBP_ENCODER_ABI_VERSION); } // Returns true if 'config' is non-NULL and all configuration parameters are // within their valid ranges. WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config); //------------------------------------------------------------------------------ // Input / Output // Structure for storing auxiliary statistics (mostly for lossy encoding). struct WebPAuxStats { int coded_size; // final size float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha int block_count[3]; // number of intra4/intra16/skipped macroblocks int header_bytes[2]; // approximate number of bytes spent for header // and mode-partition #0 int residual_bytes[3][4]; // approximate number of bytes spent for // DC/AC/uv coefficients for each (0..3) segments. int segment_size[4]; // number of macroblocks in each segments int segment_quant[4]; // quantizer values for each segments int segment_level[4]; // filtering strength for each segments [0..63] int alpha_data_size; // size of the transparency data int layer_data_size; // size of the enhancement layer data // lossless encoder statistics uint32_t lossless_features; // bit0:predictor bit1:cross-color transform // bit2:subtract-green bit3:color indexing int histogram_bits; // number of precision bits of histogram int transform_bits; // precision bits for transform int cache_bits; // number of bits for color cache lookup int palette_size; // number of color in palette, if used int lossless_size; // final lossless size uint32_t pad[4]; // padding for later use }; // Signature for output function. Should return true if writing was successful. // data/data_size is the segment of data to write, and 'picture' is for // reference (and so one can make use of picture->custom_ptr). typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size, const WebPPicture* picture); // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using // the following WebPMemoryWriter object (to be set as a custom_ptr). struct WebPMemoryWriter { uint8_t* mem; // final buffer (of size 'max_size', larger than 'size'). size_t size; // final size size_t max_size; // total capacity uint32_t pad[1]; // padding for later use }; // The following must be called first before any use. WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer); // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon // completion, writer.mem and writer.size will hold the coded data. // writer.mem must be freed using the call 'free(writer.mem)'. WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size, const WebPPicture* picture); // Progress hook, called from time to time to report progress. It can return // false to request an abort of the encoding process, or true otherwise if // everything is OK. typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture); // Color spaces. typedef enum WebPEncCSP { // chroma sampling WEBP_YUV420 = 0, // 4:2:0 WEBP_YUV422 = 1, // 4:2:2 WEBP_YUV444 = 2, // 4:4:4 WEBP_YUV400 = 3, // grayscale WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors // alpha channel variants WEBP_YUV420A = 4, WEBP_YUV422A = 5, WEBP_YUV444A = 6, WEBP_YUV400A = 7, // grayscale + alpha WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present } WebPEncCSP; // Encoding error conditions. typedef enum WebPEncodingError { VP8_ENC_OK = 0, VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G VP8_ENC_ERROR_USER_ABORT, // abort request by user VP8_ENC_ERROR_LAST // list terminator. always last. } WebPEncodingError; // maximum width/height allowed (inclusive), in pixels #define WEBP_MAX_DIMENSION 16383 // Main exchange structure (input samples, output bytes, statistics) struct WebPPicture { // INPUT ////////////// // Main flag for encoder selecting between ARGB or YUV input. // It is recommended to use ARGB input (*argb, argb_stride) for lossless // compression, and YUV input (*y, *u, *v, etc.) for lossy compression // since these are the respective native colorspace for these formats. int use_argb; // YUV input (mostly used for input to lossy compression) WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr). int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION) uint8_t *y, *u, *v; // pointers to luma/chroma planes. int y_stride, uv_stride; // luma/chroma strides. uint8_t* a; // pointer to the alpha plane int a_stride; // stride of the alpha plane uint32_t pad1[2]; // padding for later use // ARGB input (mostly used for input to lossless compression) uint32_t* argb; // Pointer to argb (32 bit) plane. int argb_stride; // This is stride in pixels units, not bytes. uint32_t pad2[3]; // padding for later use // OUTPUT /////////////// // Byte-emission hook, to store compressed bytes as they are ready. WebPWriterFunction writer; // can be NULL void* custom_ptr; // can be used by the writer. // map for extra information (only for lossy compression mode) int extra_info_type; // 1: intra type, 2: segment, 3: quant // 4: intra-16 prediction mode, // 5: chroma prediction mode, // 6: bit cost, 7: distortion uint8_t* extra_info; // if not NULL, points to an array of size // ((width + 15) / 16) * ((height + 15) / 16) that // will be filled with a macroblock map, depending // on extra_info_type. // STATS AND REPORTS /////////////////////////// // Pointer to side statistics (updated only if not NULL) WebPAuxStats* stats; // Error code for the latest error encountered during encoding WebPEncodingError error_code; // If not NULL, report progress during encoding. WebPProgressHook progress_hook; void* user_data; // this field is free to be set to any value and // used during callbacks (like progress-report e.g.). uint32_t pad3[3]; // padding for later use // Unused for now: original samples (for non-YUV420 modes) uint8_t *u0, *v0; int uv0_stride; uint32_t pad4[7]; // padding for later use // PRIVATE FIELDS //////////////////// void* memory_; // row chunk of memory for yuva planes void* memory_argb_; // and for argb too. void* pad5[2]; // padding for later use }; // Internal, version-checked, entry point WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int); // Should always be called, to initialize the structure. Returns false in case // of version mismatch. WebPPictureInit() must have succeeded before using the // 'picture' object. // Note that, by default, use_argb is false and colorspace is WEBP_YUV420. static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) { return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION); } //------------------------------------------------------------------------------ // WebPPicture utils // Convenience allocation / deallocation based on picture->width/height: // Allocate y/u/v buffers as per colorspace/width/height specification. // Note! This function will free the previous buffer if needed. // Returns false in case of memory error. WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture); // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*(). // Note that this function does _not_ free the memory used by the 'picture' // object itself. // Besides memory (which is reclaimed) all other fields of 'picture' are // preserved. WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture); // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst // will fully own the copied pixels (this is not a view). The 'dst' picture need // not be initialized as its content is overwritten. // Returns false in case of memory allocation error. WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst); // Compute PSNR, SSIM or LSIM distortion metric between two pictures. // Result is in dB, stores in result[] in the Y/U/V/Alpha/All order. // Returns false in case of error (src and ref don't have same dimension, ...) // Warning: this function is rather CPU-intensive. WEBP_EXTERN(int) WebPPictureDistortion( const WebPPicture* src, const WebPPicture* ref, int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM float result[5]); // self-crops a picture to the rectangle defined by top/left/width/height. // Returns false in case of memory allocation error, or if the rectangle is // outside of the source picture. // The rectangle for the view is defined by the top-left corner pixel // coordinates (left, top) as well as its width and height. This rectangle // must be fully be comprised inside the 'src' source picture. If the source // picture uses the YUV420 colorspace, the top and left coordinates will be // snapped to even values. WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture, int left, int top, int width, int height); // Extracts a view from 'src' picture into 'dst'. The rectangle for the view // is defined by the top-left corner pixel coordinates (left, top) as well // as its width and height. This rectangle must be fully be comprised inside // the 'src' source picture. If the source picture uses the YUV420 colorspace, // the top and left coordinates will be snapped to even values. // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so, // the original dimension will be lost). Picture 'dst' need not be initialized // with WebPPictureInit() if it is different from 'src', since its content will // be overwritten. // Returns false in case of memory allocation error or invalid parameters. WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src, int left, int top, int width, int height, WebPPicture* dst); // Returns true if the 'picture' is actually a view and therefore does // not own the memory for pixels. WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture); // Rescale a picture to new dimension width x height. // Now gamma correction is applied. // Returns false in case of error (invalid parameter or insufficient memory). WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height); // Colorspace conversion function to import RGB samples. // Previous buffer will be free'd, if any. // *rgb buffer should have a size of at least height * rgb_stride. // Returns false in case of memory error. WEBP_EXTERN(int) WebPPictureImportRGB( WebPPicture* picture, const uint8_t* rgb, int rgb_stride); // Same, but for RGBA buffer. WEBP_EXTERN(int) WebPPictureImportRGBA( WebPPicture* picture, const uint8_t* rgba, int rgba_stride); // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format // input buffer ignoring the alpha channel. Avoids needing to copy the data // to a temporary 24-bit RGB buffer to import the RGB only. WEBP_EXTERN(int) WebPPictureImportRGBX( WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride); // Variants of the above, but taking BGR(A|X) input. WEBP_EXTERN(int) WebPPictureImportBGR( WebPPicture* picture, const uint8_t* bgr, int bgr_stride); WEBP_EXTERN(int) WebPPictureImportBGRA( WebPPicture* picture, const uint8_t* bgra, int bgra_stride); WEBP_EXTERN(int) WebPPictureImportBGRX( WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride); // Converts picture->argb data to the YUVA format specified by 'colorspace'. // Upon return, picture->use_argb is set to false. The presence of real // non-opaque transparent values is detected, and 'colorspace' will be // adjusted accordingly. Note that this method is lossy. // Returns false in case of error. WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace); // Same as WebPPictureARGBToYUVA(), but the conversion is done using // pseudo-random dithering with a strength 'dithering' between // 0.0 (no dithering) and 1.0 (maximum dithering). This is useful // for photographic picture. WEBP_EXTERN(int) WebPPictureARGBToYUVADithered( WebPPicture* picture, WebPEncCSP colorspace, float dithering); // Converts picture->yuv to picture->argb and sets picture->use_argb to true. // The input format must be YUV_420 or YUV_420A. // Note that the use of this method is discouraged if one has access to the // raw ARGB samples, since using YUV420 is comparatively lossy. Also, the // conversion from YUV420 to ARGB incurs a small loss too. // Returns false in case of error. WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture); // Helper function: given a width x height plane of YUV(A) samples // (with stride 'stride'), clean-up the YUV samples under fully transparent // area, to help compressibility (no guarantee, though). WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture); // Scan the picture 'picture' for the presence of non fully opaque alpha values. // Returns true in such case. Otherwise returns false (indicating that the // alpha plane can be ignored altogether e.g.). WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture); // Remove the transparency information (if present) by blending the color with // the background color 'background_rgb' (specified as 24bit RGB triplet). // After this call, all alpha values are reset to 0xff. WEBP_EXTERN(void) WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb); //------------------------------------------------------------------------------ // Main call // Main encoding call, after config and picture have been initialized. // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION), // and the 'config' object must be a valid one. // Returns false in case of error, true otherwise. // In case of error, picture->error_code is updated accordingly. // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending // on the value of 'picture->use_argb'. It is highly recommended to use // the former for lossy encoding, and the latter for lossless encoding // (when config.lossless is true). Automatic conversion from one format to // another is provided but they both incur some loss. WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_ENCODE_H_ */ libwebp-0.4.0/src/webp/format_constants.h0000644000014400001440000000753212255002107015331 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Internal header for constants related to WebP file format. // // Author: Urvang (urvang@google.com) #ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_ #define WEBP_WEBP_FORMAT_CONSTANTS_H_ // Create fourcc of the chunk from the chunk tag characters. #define MKFOURCC(a, b, c, d) ((uint32_t)(a) | (b) << 8 | (c) << 16 | (d) << 24) // VP8 related constants. #define VP8_SIGNATURE 0x9d012a // Signature in VP8 data. #define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition #define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition #define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. // VP8L related constants. #define VP8L_SIGNATURE_SIZE 1 // VP8L signature size. #define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte. #define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store // width and height. #define VP8L_VERSION_BITS 3 // 3 bits reserved for version. #define VP8L_VERSION 0 // version 0 #define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header. #define MAX_PALETTE_SIZE 256 #define MAX_CACHE_BITS 11 #define HUFFMAN_CODES_PER_META_CODE 5 #define ARGB_BLACK 0xff000000 #define DEFAULT_CODE_LENGTH 8 #define MAX_ALLOWED_CODE_LENGTH 15 #define NUM_LITERAL_CODES 256 #define NUM_LENGTH_CODES 24 #define NUM_DISTANCE_CODES 40 #define CODE_LENGTH_CODES 19 #define MIN_HUFFMAN_BITS 2 // min number of Huffman bits #define MAX_HUFFMAN_BITS 9 // max number of Huffman bits #define TRANSFORM_PRESENT 1 // The bit to be written when next data // to be read is a transform. #define NUM_TRANSFORMS 4 // Maximum number of allowed transform // in a bitstream. typedef enum { PREDICTOR_TRANSFORM = 0, CROSS_COLOR_TRANSFORM = 1, SUBTRACT_GREEN = 2, COLOR_INDEXING_TRANSFORM = 3 } VP8LImageTransformType; // Alpha related constants. #define ALPHA_HEADER_LEN 1 #define ALPHA_NO_COMPRESSION 0 #define ALPHA_LOSSLESS_COMPRESSION 1 #define ALPHA_PREPROCESSED_LEVELS 1 // Mux related constants. #define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L"). #define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size. #define CHUNK_HEADER_SIZE 8 // Size of a chunk header. #define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP"). #define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk. #define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk. #define FRGM_CHUNK_SIZE 6 // Size of a FRGM chunk. #define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk. #define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height. #define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height. #define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count #define MAX_DURATION (1 << 24) // maximum duration #define MAX_POSITION_OFFSET (1 << 24) // maximum frame/fragment x/y offset // Maximum chunk payload is such that adding the header and padding won't // overflow a uint32_t. #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) #endif /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */ libwebp-0.4.0/src/webp/types.h0000644000014400001440000000265412255002107013111 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Common types // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_TYPES_H_ #define WEBP_WEBP_TYPES_H_ #include // for size_t #ifndef _MSC_VER #include #ifdef __STRICT_ANSI__ #define WEBP_INLINE #else /* __STRICT_ANSI__ */ #define WEBP_INLINE inline #endif #else typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; typedef long long int int64_t; #define WEBP_INLINE __forceinline #endif /* _MSC_VER */ #ifndef WEBP_EXTERN // This explicitly marks library functions and allows for changing the // signature for e.g., Windows DLL builds. #define WEBP_EXTERN(type) extern type #endif /* WEBP_EXTERN */ // Macro to check ABI compatibility (same major revision number) #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) #endif /* WEBP_WEBP_TYPES_H_ */ libwebp-0.4.0/src/libwebp.pc.in0000644000014400001440000000042112255002107013202 0ustar prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libwebp Description: Library for the WebP graphics format Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lwebp Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ libwebp-0.4.0/src/Makefile.am0000644000014400001440000000314012255002107012662 0ustar # The mux and demux libraries depend on libwebp, thus the '.' to force the # build order so it's available to them. SUBDIRS = dec enc dsp utils . if WANT_MUX SUBDIRS += mux endif if WANT_DEMUX SUBDIRS += demux endif AM_CPPFLAGS = -I$(top_srcdir)/src lib_LTLIBRARIES = libwebp.la if BUILD_LIBWEBPDECODER lib_LTLIBRARIES += libwebpdecoder.la endif common_HEADERS = common_HEADERS += webp/decode.h common_HEADERS += webp/types.h commondir = $(includedir)/webp libwebp_la_SOURCES = libwebpinclude_HEADERS = libwebpinclude_HEADERS += webp/encode.h noinst_HEADERS = noinst_HEADERS += webp/format_constants.h libwebp_la_LIBADD = libwebp_la_LIBADD += dec/libwebpdecode.la libwebp_la_LIBADD += dsp/libwebpdsp.la libwebp_la_LIBADD += enc/libwebpencode.la libwebp_la_LIBADD += utils/libwebputils.la # Use '-no-undefined' to declare that libwebp does not depend on any libraries # other than the ones listed on the command line, i.e., after linking, it will # not have unresolved symbols. Some platforms (Windows among them) require all # symbols in shared libraries to be resolved at library creation. libwebp_la_LDFLAGS = -no-undefined -version-info 5:0:0 libwebpincludedir = $(includedir)/webp pkgconfig_DATA = libwebp.pc if BUILD_LIBWEBPDECODER libwebpdecoder_la_SOURCES = libwebpdecoder_la_LIBADD = libwebpdecoder_la_LIBADD += dec/libwebpdecode.la libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 1:0:0 pkgconfig_DATA += libwebpdecoder.pc endif ${pkgconfig_DATA}: ${top_builddir}/config.status libwebp-0.4.0/src/demux/0000755000014400001440000000000012255206714011764 5ustar libwebp-0.4.0/src/demux/Makefile.in0000644000014400001440000005134412255206714014040 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ subdir = src/demux DIST_COMMON = $(libwebpdemuxinclude_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/libwebpdemux.pc.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libwebpdemux.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(libwebpdemuxincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libwebpdemux_la_DEPENDENCIES = ../libwebp.la am_libwebpdemux_la_OBJECTS = demux.lo libwebpdemux_la_OBJECTS = $(am_libwebpdemux_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libwebpdemux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libwebpdemux_la_LDFLAGS) $(LDFLAGS) \ -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libwebpdemux_la_SOURCES) DIST_SOURCES = $(libwebpdemux_la_SOURCES) DATA = $(pkgconfig_DATA) HEADERS = $(libwebpdemuxinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src lib_LTLIBRARIES = libwebpdemux.la libwebpdemux_la_SOURCES = demux.c libwebpdemuxinclude_HEADERS = ../webp/demux.h ../webp/mux_types.h \ ../webp/types.h libwebpdemux_la_LIBADD = ../libwebp.la libwebpdemux_la_LDFLAGS = -no-undefined -version-info 1:0:0 libwebpdemuxincludedir = $(includedir)/webp pkgconfig_DATA = libwebpdemux.pc all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign src/demux/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/demux/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libwebpdemux.pc: $(top_builddir)/config.status $(srcdir)/libwebpdemux.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebpdemux.la: $(libwebpdemux_la_OBJECTS) $(libwebpdemux_la_DEPENDENCIES) $(EXTRA_libwebpdemux_la_DEPENDENCIES) $(AM_V_CCLD)$(libwebpdemux_la_LINK) -rpath $(libdir) $(libwebpdemux_la_OBJECTS) $(libwebpdemux_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demux.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-libwebpdemuxincludeHEADERS: $(libwebpdemuxinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(libwebpdemuxincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libwebpdemuxincludedir)" @list='$(libwebpdemuxinclude_HEADERS)'; test -n "$(libwebpdemuxincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpdemuxincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpdemuxincludedir)" || exit $$?; \ done uninstall-libwebpdemuxincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libwebpdemuxinclude_HEADERS)'; test -n "$(libwebpdemuxincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libwebpdemuxincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libwebpdemuxincludedir)"; 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-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-libwebpdemuxincludeHEADERS \ install-pkgconfigDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES 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 -rf ./$(DEPDIR) -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-libLTLIBRARIES \ uninstall-libwebpdemuxincludeHEADERS uninstall-pkgconfigDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES install-libwebpdemuxincludeHEADERS \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ 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 uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-libwebpdemuxincludeHEADERS uninstall-pkgconfigDATA # 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: libwebp-0.4.0/src/demux/libwebpdemux.pc.in0000644000014400001440000000042612255002107015374 0ustar prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libwebpdemux Description: Library for parsing the WebP graphics format container Version: @PACKAGE_VERSION@ Requires: libwebp >= 0.2.0 Cflags: -I${includedir} Libs: -L${libdir} -lwebpdemux libwebp-0.4.0/src/demux/Makefile.am0000644000014400001440000000074312255002107014012 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src lib_LTLIBRARIES = libwebpdemux.la libwebpdemux_la_SOURCES = libwebpdemux_la_SOURCES += demux.c libwebpdemuxinclude_HEADERS = libwebpdemuxinclude_HEADERS += ../webp/demux.h libwebpdemuxinclude_HEADERS += ../webp/mux_types.h libwebpdemuxinclude_HEADERS += ../webp/types.h libwebpdemux_la_LIBADD = ../libwebp.la libwebpdemux_la_LDFLAGS = -no-undefined -version-info 1:0:0 libwebpdemuxincludedir = $(includedir)/webp pkgconfig_DATA = libwebpdemux.pc libwebp-0.4.0/src/demux/demux.c0000644000014400001440000010123712255002107013244 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // WebP container demux. // #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "../utils/utils.h" #include "../webp/decode.h" // WebPGetFeatures #include "../webp/demux.h" #include "../webp/format_constants.h" #define DMUX_MAJ_VERSION 0 #define DMUX_MIN_VERSION 2 #define DMUX_REV_VERSION 0 typedef struct { size_t start_; // start location of the data size_t end_; // end location size_t riff_end_; // riff chunk end location, can be > end_. size_t buf_size_; // size of the buffer const uint8_t* buf_; } MemBuffer; typedef struct { size_t offset_; size_t size_; } ChunkData; typedef struct Frame { int x_offset_, y_offset_; int width_, height_; int has_alpha_; int duration_; WebPMuxAnimDispose dispose_method_; WebPMuxAnimBlend blend_method_; int is_fragment_; // this is a frame fragment (and not a full frame). int frame_num_; // the referent frame number for use in assembling fragments. int complete_; // img_components_ contains a full image. ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH struct Frame* next_; } Frame; typedef struct Chunk { ChunkData data_; struct Chunk* next_; } Chunk; struct WebPDemuxer { MemBuffer mem_; WebPDemuxState state_; int is_ext_format_; uint32_t feature_flags_; int canvas_width_, canvas_height_; int loop_count_; uint32_t bgcolor_; int num_frames_; Frame* frames_; Frame** frames_tail_; Chunk* chunks_; // non-image chunks Chunk** chunks_tail_; }; typedef enum { PARSE_OK, PARSE_NEED_MORE_DATA, PARSE_ERROR } ParseStatus; typedef struct ChunkParser { uint8_t id[4]; ParseStatus (*parse)(WebPDemuxer* const dmux); int (*valid)(const WebPDemuxer* const dmux); } ChunkParser; static ParseStatus ParseSingleImage(WebPDemuxer* const dmux); static ParseStatus ParseVP8X(WebPDemuxer* const dmux); static int IsValidSimpleFormat(const WebPDemuxer* const dmux); static int IsValidExtendedFormat(const WebPDemuxer* const dmux); static const ChunkParser kMasterChunks[] = { { { 'V', 'P', '8', ' ' }, ParseSingleImage, IsValidSimpleFormat }, { { 'V', 'P', '8', 'L' }, ParseSingleImage, IsValidSimpleFormat }, { { 'V', 'P', '8', 'X' }, ParseVP8X, IsValidExtendedFormat }, { { '0', '0', '0', '0' }, NULL, NULL }, }; //------------------------------------------------------------------------------ int WebPGetDemuxVersion(void) { return (DMUX_MAJ_VERSION << 16) | (DMUX_MIN_VERSION << 8) | DMUX_REV_VERSION; } // ----------------------------------------------------------------------------- // MemBuffer static int RemapMemBuffer(MemBuffer* const mem, const uint8_t* data, size_t size) { if (size < mem->buf_size_) return 0; // can't remap to a shorter buffer! mem->buf_ = data; mem->end_ = mem->buf_size_ = size; return 1; } static int InitMemBuffer(MemBuffer* const mem, const uint8_t* data, size_t size) { memset(mem, 0, sizeof(*mem)); return RemapMemBuffer(mem, data, size); } // Return the remaining data size available in 'mem'. static WEBP_INLINE size_t MemDataSize(const MemBuffer* const mem) { return (mem->end_ - mem->start_); } // Return true if 'size' exceeds the end of the RIFF chunk. static WEBP_INLINE int SizeIsInvalid(const MemBuffer* const mem, size_t size) { return (size > mem->riff_end_ - mem->start_); } static WEBP_INLINE void Skip(MemBuffer* const mem, size_t size) { mem->start_ += size; } static WEBP_INLINE void Rewind(MemBuffer* const mem, size_t size) { mem->start_ -= size; } static WEBP_INLINE const uint8_t* GetBuffer(MemBuffer* const mem) { return mem->buf_ + mem->start_; } // Read from 'mem' and skip the read bytes. static WEBP_INLINE uint8_t ReadByte(MemBuffer* const mem) { const uint8_t byte = mem->buf_[mem->start_]; Skip(mem, 1); return byte; } static WEBP_INLINE int ReadLE16s(MemBuffer* const mem) { const uint8_t* const data = mem->buf_ + mem->start_; const int val = GetLE16(data); Skip(mem, 2); return val; } static WEBP_INLINE int ReadLE24s(MemBuffer* const mem) { const uint8_t* const data = mem->buf_ + mem->start_; const int val = GetLE24(data); Skip(mem, 3); return val; } static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) { const uint8_t* const data = mem->buf_ + mem->start_; const uint32_t val = GetLE32(data); Skip(mem, 4); return val; } // ----------------------------------------------------------------------------- // Secondary chunk parsing static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) { *dmux->chunks_tail_ = chunk; chunk->next_ = NULL; dmux->chunks_tail_ = &chunk->next_; } // Add a frame to the end of the list, ensuring the last frame is complete. // Returns true on success, false otherwise. static int AddFrame(WebPDemuxer* const dmux, Frame* const frame) { const Frame* const last_frame = *dmux->frames_tail_; if (last_frame != NULL && !last_frame->complete_) return 0; *dmux->frames_tail_ = frame; frame->next_ = NULL; dmux->frames_tail_ = &frame->next_; return 1; } // Store image bearing chunks to 'frame'. static ParseStatus StoreFrame(int frame_num, uint32_t min_size, MemBuffer* const mem, Frame* const frame) { int alpha_chunks = 0; int image_chunks = 0; int done = (MemDataSize(mem) < min_size); ParseStatus status = PARSE_OK; if (done) return PARSE_NEED_MORE_DATA; do { const size_t chunk_start_offset = mem->start_; const uint32_t fourcc = ReadLE32(mem); const uint32_t payload_size = ReadLE32(mem); const uint32_t payload_size_padded = payload_size + (payload_size & 1); const size_t payload_available = (payload_size_padded > MemDataSize(mem)) ? MemDataSize(mem) : payload_size_padded; const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available; if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR; if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA; switch (fourcc) { case MKFOURCC('A', 'L', 'P', 'H'): if (alpha_chunks == 0) { ++alpha_chunks; frame->img_components_[1].offset_ = chunk_start_offset; frame->img_components_[1].size_ = chunk_size; frame->has_alpha_ = 1; frame->frame_num_ = frame_num; Skip(mem, payload_available); } else { goto Done; } break; case MKFOURCC('V', 'P', '8', 'L'): if (alpha_chunks > 0) return PARSE_ERROR; // VP8L has its own alpha // fall through case MKFOURCC('V', 'P', '8', ' '): if (image_chunks == 0) { // Extract the bitstream features, tolerating failures when the data // is incomplete. WebPBitstreamFeatures features; const VP8StatusCode vp8_status = WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size, &features); if (status == PARSE_NEED_MORE_DATA && vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) { return PARSE_NEED_MORE_DATA; } else if (vp8_status != VP8_STATUS_OK) { // We have enough data, and yet WebPGetFeatures() failed. return PARSE_ERROR; } ++image_chunks; frame->img_components_[0].offset_ = chunk_start_offset; frame->img_components_[0].size_ = chunk_size; frame->width_ = features.width; frame->height_ = features.height; frame->has_alpha_ |= features.has_alpha; frame->frame_num_ = frame_num; frame->complete_ = (status == PARSE_OK); Skip(mem, payload_available); } else { goto Done; } break; Done: default: // Restore fourcc/size when moving up one level in parsing. Rewind(mem, CHUNK_HEADER_SIZE); done = 1; break; } if (mem->start_ == mem->riff_end_) { done = 1; } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { status = PARSE_NEED_MORE_DATA; } } while (!done && status == PARSE_OK); return status; } // Creates a new Frame if 'actual_size' is within bounds and 'mem' contains // enough data ('min_size') to parse the payload. // Returns PARSE_OK on success with *frame pointing to the new Frame. // Returns PARSE_NEED_MORE_DATA with insufficient data, PARSE_ERROR otherwise. static ParseStatus NewFrame(const MemBuffer* const mem, uint32_t min_size, uint32_t actual_size, Frame** frame) { if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR; if (actual_size < min_size) return PARSE_ERROR; if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; *frame = (Frame*)calloc(1, sizeof(**frame)); return (*frame == NULL) ? PARSE_ERROR : PARSE_OK; } // Parse a 'ANMF' chunk and any image bearing chunks that immediately follow. // 'frame_chunk_size' is the previously validated, padded chunk size. static ParseStatus ParseAnimationFrame( WebPDemuxer* const dmux, uint32_t frame_chunk_size) { const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE; int added_frame = 0; int bits; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status = NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame); if (status != PARSE_OK) return status; frame->x_offset_ = 2 * ReadLE24s(mem); frame->y_offset_ = 2 * ReadLE24s(mem); frame->width_ = 1 + ReadLE24s(mem); frame->height_ = 1 + ReadLE24s(mem); frame->duration_ = ReadLE24s(mem); bits = ReadByte(mem); frame->dispose_method_ = (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND; if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) { free(frame); return PARSE_ERROR; } // Store a frame only if the animation flag is set there is some data for // this frame is available. status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame); if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) { added_frame = AddFrame(dmux, frame); if (added_frame) { ++dmux->num_frames_; } else { status = PARSE_ERROR; } } if (!added_frame) free(frame); return status; } #ifdef WEBP_EXPERIMENTAL_FEATURES // Parse a 'FRGM' chunk and any image bearing chunks that immediately follow. // 'fragment_chunk_size' is the previously validated, padded chunk size. static ParseStatus ParseFragment(WebPDemuxer* const dmux, uint32_t fragment_chunk_size) { const int frame_num = 1; // All fragments belong to the 1st (and only) frame. const int is_fragmented = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); const uint32_t frgm_payload_size = fragment_chunk_size - FRGM_CHUNK_SIZE; int added_fragment = 0; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status = NewFrame(mem, FRGM_CHUNK_SIZE, fragment_chunk_size, &frame); if (status != PARSE_OK) return status; frame->is_fragment_ = 1; frame->x_offset_ = 2 * ReadLE24s(mem); frame->y_offset_ = 2 * ReadLE24s(mem); // Store a fragment only if the 'fragments' flag is set and there is some // data available. status = StoreFrame(frame_num, frgm_payload_size, mem, frame); if (status != PARSE_ERROR && is_fragmented && frame->frame_num_ > 0) { added_fragment = AddFrame(dmux, frame); if (!added_fragment) { status = PARSE_ERROR; } else { dmux->num_frames_ = 1; } } if (!added_fragment) free(frame); return status; } #endif // WEBP_EXPERIMENTAL_FEATURES // General chunk storage, starting with the header at 'start_offset', allowing // the user to request the payload via a fourcc string. 'size' includes the // header and the unpadded payload size. // Returns true on success, false otherwise. static int StoreChunk(WebPDemuxer* const dmux, size_t start_offset, uint32_t size) { Chunk* const chunk = (Chunk*)calloc(1, sizeof(*chunk)); if (chunk == NULL) return 0; chunk->data_.offset_ = start_offset; chunk->data_.size_ = size; AddChunk(dmux, chunk); return 1; } // ----------------------------------------------------------------------------- // Primary chunk parsing static ParseStatus ReadHeader(MemBuffer* const mem) { const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE; uint32_t riff_size; // Basic file level validation. if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; if (memcmp(GetBuffer(mem), "RIFF", CHUNK_SIZE_BYTES) || memcmp(GetBuffer(mem) + CHUNK_HEADER_SIZE, "WEBP", CHUNK_SIZE_BYTES)) { return PARSE_ERROR; } riff_size = GetLE32(GetBuffer(mem) + TAG_SIZE); if (riff_size < CHUNK_HEADER_SIZE) return PARSE_ERROR; if (riff_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; // There's no point in reading past the end of the RIFF chunk mem->riff_end_ = riff_size + CHUNK_HEADER_SIZE; if (mem->buf_size_ > mem->riff_end_) { mem->buf_size_ = mem->end_ = mem->riff_end_; } Skip(mem, RIFF_HEADER_SIZE); return PARSE_OK; } static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { const size_t min_size = CHUNK_HEADER_SIZE; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status; int image_added = 0; if (dmux->frames_ != NULL) return PARSE_ERROR; if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR; if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; frame = (Frame*)calloc(1, sizeof(*frame)); if (frame == NULL) return PARSE_ERROR; // For the single image case we allow parsing of a partial frame, but we need // at least CHUNK_HEADER_SIZE for parsing. status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame); if (status != PARSE_ERROR) { const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG); // Clear any alpha when the alpha flag is missing. if (!has_alpha && frame->img_components_[1].size_ > 0) { frame->img_components_[1].offset_ = 0; frame->img_components_[1].size_ = 0; frame->has_alpha_ = 0; } // Use the frame width/height as the canvas values for non-vp8x files. // Also, set ALPHA_FLAG if this is a lossless image with alpha. if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) { dmux->state_ = WEBP_DEMUX_PARSED_HEADER; dmux->canvas_width_ = frame->width_; dmux->canvas_height_ = frame->height_; dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0; } if (!AddFrame(dmux, frame)) { status = PARSE_ERROR; // last frame was left incomplete } else { image_added = 1; dmux->num_frames_ = 1; } } if (!image_added) free(frame); return status; } static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); MemBuffer* const mem = &dmux->mem_; int anim_chunks = 0; ParseStatus status = PARSE_OK; do { int store_chunk = 1; const size_t chunk_start_offset = mem->start_; const uint32_t fourcc = ReadLE32(mem); const uint32_t chunk_size = ReadLE32(mem); const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1); if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR; switch (fourcc) { case MKFOURCC('V', 'P', '8', 'X'): { return PARSE_ERROR; } case MKFOURCC('A', 'L', 'P', 'H'): case MKFOURCC('V', 'P', '8', ' '): case MKFOURCC('V', 'P', '8', 'L'): { // check that this isn't an animation (all frames should be in an ANMF). if (anim_chunks > 0 || is_animation) return PARSE_ERROR; Rewind(mem, CHUNK_HEADER_SIZE); status = ParseSingleImage(dmux); break; } case MKFOURCC('A', 'N', 'I', 'M'): { if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR; if (MemDataSize(mem) < chunk_size_padded) { status = PARSE_NEED_MORE_DATA; } else if (anim_chunks == 0) { ++anim_chunks; dmux->bgcolor_ = ReadLE32(mem); dmux->loop_count_ = ReadLE16s(mem); Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE); } else { store_chunk = 0; goto Skip; } break; } case MKFOURCC('A', 'N', 'M', 'F'): { if (anim_chunks == 0) return PARSE_ERROR; // 'ANIM' precedes frames. status = ParseAnimationFrame(dmux, chunk_size_padded); break; } #ifdef WEBP_EXPERIMENTAL_FEATURES case MKFOURCC('F', 'R', 'G', 'M'): { status = ParseFragment(dmux, chunk_size_padded); break; } #endif case MKFOURCC('I', 'C', 'C', 'P'): { store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG); goto Skip; } case MKFOURCC('E', 'X', 'I', 'F'): { store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG); goto Skip; } case MKFOURCC('X', 'M', 'P', ' '): { store_chunk = !!(dmux->feature_flags_ & XMP_FLAG); goto Skip; } Skip: default: { if (chunk_size_padded <= MemDataSize(mem)) { if (store_chunk) { // Store only the chunk header and unpadded size as only the payload // will be returned to the user. if (!StoreChunk(dmux, chunk_start_offset, CHUNK_HEADER_SIZE + chunk_size)) { return PARSE_ERROR; } } Skip(mem, chunk_size_padded); } else { status = PARSE_NEED_MORE_DATA; } } } if (mem->start_ == mem->riff_end_) { break; } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { status = PARSE_NEED_MORE_DATA; } } while (status == PARSE_OK); return status; } static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { MemBuffer* const mem = &dmux->mem_; uint32_t vp8x_size; if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; dmux->is_ext_format_ = 1; Skip(mem, TAG_SIZE); // VP8X vp8x_size = ReadLE32(mem); if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR; vp8x_size += vp8x_size & 1; if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR; if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA; dmux->feature_flags_ = ReadByte(mem); Skip(mem, 3); // Reserved. dmux->canvas_width_ = 1 + ReadLE24s(mem); dmux->canvas_height_ = 1 + ReadLE24s(mem); if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) { return PARSE_ERROR; // image final dimension is too large } Skip(mem, vp8x_size - VP8X_CHUNK_SIZE); // skip any trailing data. dmux->state_ = WEBP_DEMUX_PARSED_HEADER; if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR; if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; return ParseVP8XChunks(dmux); } // ----------------------------------------------------------------------------- // Format validation static int IsValidSimpleFormat(const WebPDemuxer* const dmux) { const Frame* const frame = dmux->frames_; if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0; if (frame->width_ <= 0 || frame->height_ <= 0) return 0; return 1; } // If 'exact' is true, check that the image resolution matches the canvas. // If 'exact' is false, check that the x/y offsets do not exceed the canvas. // TODO(jzern): this is insufficient in the fragmented image case if the // expectation is that the fragments completely cover the canvas. static int CheckFrameBounds(const Frame* const frame, int exact, int canvas_width, int canvas_height) { if (exact) { if (frame->x_offset_ != 0 || frame->y_offset_ != 0) { return 0; } if (frame->width_ != canvas_width || frame->height_ != canvas_height) { return 0; } } else { if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0; if (frame->width_ + frame->x_offset_ > canvas_width) return 0; if (frame->height_ + frame->y_offset_ > canvas_height) return 0; } return 1; } static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); const int is_fragmented = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); const Frame* f = dmux->frames_; if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; if (dmux->loop_count_ < 0) return 0; if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; #ifndef WEBP_EXPERIMENTAL_FEATURES if (is_fragmented) return 0; #endif while (f != NULL) { const int cur_frame_set = f->frame_num_; int frame_count = 0, fragment_count = 0; // Check frame properties and if the image is composed of fragments that // each fragment came from a fragment. for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { const ChunkData* const image = f->img_components_; const ChunkData* const alpha = f->img_components_ + 1; if (is_fragmented && !f->is_fragment_) return 0; if (!is_fragmented && f->is_fragment_) return 0; if (!is_animation && f->frame_num_ > 1) return 0; if (f->complete_) { if (alpha->size_ == 0 && image->size_ == 0) return 0; // Ensure alpha precedes image bitstream. if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { return 0; } if (f->width_ <= 0 || f->height_ <= 0) return 0; } else { // There shouldn't be a partial frame in a complete file. if (dmux->state_ == WEBP_DEMUX_DONE) return 0; // Ensure alpha precedes image bitstream. if (alpha->size_ > 0 && image->size_ > 0 && alpha->offset_ > image->offset_) { return 0; } // There shouldn't be any frames after an incomplete one. if (f->next_ != NULL) return 0; } if (f->width_ > 0 && f->height_ > 0 && !CheckFrameBounds(f, !(is_animation || is_fragmented), dmux->canvas_width_, dmux->canvas_height_)) { return 0; } fragment_count += f->is_fragment_; ++frame_count; } if (!is_fragmented && frame_count > 1) return 0; if (fragment_count > 0 && frame_count != fragment_count) return 0; } return 1; } // ----------------------------------------------------------------------------- // WebPDemuxer object static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) { dmux->state_ = WEBP_DEMUX_PARSING_HEADER; dmux->loop_count_ = 1; dmux->bgcolor_ = 0xFFFFFFFF; // White background by default. dmux->canvas_width_ = -1; dmux->canvas_height_ = -1; dmux->frames_tail_ = &dmux->frames_; dmux->chunks_tail_ = &dmux->chunks_; dmux->mem_ = *mem; } WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial, WebPDemuxState* state, int version) { const ChunkParser* parser; int partial; ParseStatus status = PARSE_ERROR; MemBuffer mem; WebPDemuxer* dmux; if (state != NULL) *state = WEBP_DEMUX_PARSE_ERROR; if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DEMUX_ABI_VERSION)) return NULL; if (data == NULL || data->bytes == NULL || data->size == 0) return NULL; if (!InitMemBuffer(&mem, data->bytes, data->size)) return NULL; status = ReadHeader(&mem); if (status != PARSE_OK) { if (state != NULL) { *state = (status == PARSE_NEED_MORE_DATA) ? WEBP_DEMUX_PARSING_HEADER : WEBP_DEMUX_PARSE_ERROR; } return NULL; } partial = (mem.buf_size_ < mem.riff_end_); if (!allow_partial && partial) return NULL; dmux = (WebPDemuxer*)calloc(1, sizeof(*dmux)); if (dmux == NULL) return NULL; InitDemux(dmux, &mem); status = PARSE_ERROR; for (parser = kMasterChunks; parser->parse != NULL; ++parser) { if (!memcmp(parser->id, GetBuffer(&dmux->mem_), TAG_SIZE)) { status = parser->parse(dmux); if (status == PARSE_OK) dmux->state_ = WEBP_DEMUX_DONE; if (status == PARSE_NEED_MORE_DATA && !partial) status = PARSE_ERROR; if (status != PARSE_ERROR && !parser->valid(dmux)) status = PARSE_ERROR; if (status == PARSE_ERROR) dmux->state_ = WEBP_DEMUX_PARSE_ERROR; break; } } if (state != NULL) *state = dmux->state_; if (status == PARSE_ERROR) { WebPDemuxDelete(dmux); return NULL; } return dmux; } void WebPDemuxDelete(WebPDemuxer* dmux) { Chunk* c; Frame* f; if (dmux == NULL) return; for (f = dmux->frames_; f != NULL;) { Frame* const cur_frame = f; f = f->next_; free(cur_frame); } for (c = dmux->chunks_; c != NULL;) { Chunk* const cur_chunk = c; c = c->next_; free(cur_chunk); } free(dmux); } // ----------------------------------------------------------------------------- uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) { if (dmux == NULL) return 0; switch (feature) { case WEBP_FF_FORMAT_FLAGS: return dmux->feature_flags_; case WEBP_FF_CANVAS_WIDTH: return (uint32_t)dmux->canvas_width_; case WEBP_FF_CANVAS_HEIGHT: return (uint32_t)dmux->canvas_height_; case WEBP_FF_LOOP_COUNT: return (uint32_t)dmux->loop_count_; case WEBP_FF_BACKGROUND_COLOR: return dmux->bgcolor_; case WEBP_FF_FRAME_COUNT: return (uint32_t)dmux->num_frames_; } return 0; } // ----------------------------------------------------------------------------- // Frame iteration // Find the first 'frame_num' frame. There may be multiple such frames in a // fragmented frame. static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) { const Frame* f; for (f = dmux->frames_; f != NULL; f = f->next_) { if (frame_num == f->frame_num_) break; } return f; } // Returns fragment 'fragment_num' and the total count. static const Frame* GetFragment( const Frame* const frame_set, int fragment_num, int* const count) { const int this_frame = frame_set->frame_num_; const Frame* f = frame_set; const Frame* fragment = NULL; int total; for (total = 0; f != NULL && f->frame_num_ == this_frame; f = f->next_) { if (++total == fragment_num) fragment = f; } *count = total; return fragment; } static const uint8_t* GetFramePayload(const uint8_t* const mem_buf, const Frame* const frame, size_t* const data_size) { *data_size = 0; if (frame != NULL) { const ChunkData* const image = frame->img_components_; const ChunkData* const alpha = frame->img_components_ + 1; size_t start_offset = image->offset_; *data_size = image->size_; // if alpha exists it precedes image, update the size allowing for // intervening chunks. if (alpha->size_ > 0) { const size_t inter_size = (image->offset_ > 0) ? image->offset_ - (alpha->offset_ + alpha->size_) : 0; start_offset = alpha->offset_; *data_size += alpha->size_ + inter_size; } return mem_buf + start_offset; } return NULL; } // Create a whole 'frame' from VP8 (+ alpha) or lossless. static int SynthesizeFrame(const WebPDemuxer* const dmux, const Frame* const first_frame, int fragment_num, WebPIterator* const iter) { const uint8_t* const mem_buf = dmux->mem_.buf_; int num_fragments; size_t payload_size = 0; const Frame* const fragment = GetFragment(first_frame, fragment_num, &num_fragments); const uint8_t* const payload = GetFramePayload(mem_buf, fragment, &payload_size); if (payload == NULL) return 0; assert(first_frame != NULL); iter->frame_num = first_frame->frame_num_; iter->num_frames = dmux->num_frames_; iter->fragment_num = fragment_num; iter->num_fragments = num_fragments; iter->x_offset = fragment->x_offset_; iter->y_offset = fragment->y_offset_; iter->width = fragment->width_; iter->height = fragment->height_; iter->has_alpha = fragment->has_alpha_; iter->duration = fragment->duration_; iter->dispose_method = fragment->dispose_method_; iter->blend_method = fragment->blend_method_; iter->complete = fragment->complete_; iter->fragment.bytes = payload; iter->fragment.size = payload_size; // TODO(jzern): adjust offsets for 'FRGM's embedded in 'ANMF's return 1; } static int SetFrame(int frame_num, WebPIterator* const iter) { const Frame* frame; const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; if (dmux == NULL || frame_num < 0) return 0; if (frame_num > dmux->num_frames_) return 0; if (frame_num == 0) frame_num = dmux->num_frames_; frame = GetFrame(dmux, frame_num); if (frame == NULL) return 0; return SynthesizeFrame(dmux, frame, 1, iter); } int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) { if (iter == NULL) return 0; memset(iter, 0, sizeof(*iter)); iter->private_ = (void*)dmux; return SetFrame(frame, iter); } int WebPDemuxNextFrame(WebPIterator* iter) { if (iter == NULL) return 0; return SetFrame(iter->frame_num + 1, iter); } int WebPDemuxPrevFrame(WebPIterator* iter) { if (iter == NULL) return 0; if (iter->frame_num <= 1) return 0; return SetFrame(iter->frame_num - 1, iter); } int WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num) { if (iter != NULL && iter->private_ != NULL && fragment_num > 0) { const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; const Frame* const frame = GetFrame(dmux, iter->frame_num); if (frame == NULL) return 0; return SynthesizeFrame(dmux, frame, fragment_num, iter); } return 0; } void WebPDemuxReleaseIterator(WebPIterator* iter) { (void)iter; } // ----------------------------------------------------------------------------- // Chunk iteration static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) { const uint8_t* const mem_buf = dmux->mem_.buf_; const Chunk* c; int count = 0; for (c = dmux->chunks_; c != NULL; c = c->next_) { const uint8_t* const header = mem_buf + c->data_.offset_; if (!memcmp(header, fourcc, TAG_SIZE)) ++count; } return count; } static const Chunk* GetChunk(const WebPDemuxer* const dmux, const char fourcc[4], int chunk_num) { const uint8_t* const mem_buf = dmux->mem_.buf_; const Chunk* c; int count = 0; for (c = dmux->chunks_; c != NULL; c = c->next_) { const uint8_t* const header = mem_buf + c->data_.offset_; if (!memcmp(header, fourcc, TAG_SIZE)) ++count; if (count == chunk_num) break; } return c; } static int SetChunk(const char fourcc[4], int chunk_num, WebPChunkIterator* const iter) { const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; int count; if (dmux == NULL || fourcc == NULL || chunk_num < 0) return 0; count = ChunkCount(dmux, fourcc); if (count == 0) return 0; if (chunk_num == 0) chunk_num = count; if (chunk_num <= count) { const uint8_t* const mem_buf = dmux->mem_.buf_; const Chunk* const chunk = GetChunk(dmux, fourcc, chunk_num); iter->chunk.bytes = mem_buf + chunk->data_.offset_ + CHUNK_HEADER_SIZE; iter->chunk.size = chunk->data_.size_ - CHUNK_HEADER_SIZE; iter->num_chunks = count; iter->chunk_num = chunk_num; return 1; } return 0; } int WebPDemuxGetChunk(const WebPDemuxer* dmux, const char fourcc[4], int chunk_num, WebPChunkIterator* iter) { if (iter == NULL) return 0; memset(iter, 0, sizeof(*iter)); iter->private_ = (void*)dmux; return SetChunk(fourcc, chunk_num, iter); } int WebPDemuxNextChunk(WebPChunkIterator* iter) { if (iter != NULL) { const char* const fourcc = (const char*)iter->chunk.bytes - CHUNK_HEADER_SIZE; return SetChunk(fourcc, iter->chunk_num + 1, iter); } return 0; } int WebPDemuxPrevChunk(WebPChunkIterator* iter) { if (iter != NULL && iter->chunk_num > 1) { const char* const fourcc = (const char*)iter->chunk.bytes - CHUNK_HEADER_SIZE; return SetChunk(fourcc, iter->chunk_num - 1, iter); } return 0; } void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { (void)iter; } libwebp-0.4.0/configure.ac0000644000014400001440000003553112255002107012336 0ustar AC_INIT([libwebp], [0.4.0], [http://code.google.com/p/webp/issues],, [http://developers.google.com/speed/webp]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) dnl === automake >= 1.12 requires this for 'unusual archivers' support. dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL). m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LIBTOOL AM_PROG_CC_C_O dnl === Enable less verbose output when building. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl === SET_IF_UNSET(shell_var, value) dnl === Set the shell variable 'shell_var' to 'value' if it is unset. AC_DEFUN([SET_IF_UNSET], [test "${$1+set}" = "set" || $1=$2]) AC_ARG_ENABLE([everything], AS_HELP_STRING([--enable-everything], [Enable all optional targets. These can still be disabled with --disable-target]), [SET_IF_UNSET([enable_libwebpdecoder], [$enableval]) SET_IF_UNSET([enable_libwebpdemux], [$enableval]) SET_IF_UNSET([enable_libwebpmux], [$enableval])]) AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=DIR], [Path to the pkgconfig directory @<:@LIBDIR/pkgconfig@:>@]), [pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig']) AC_SUBST([pkgconfigdir]) dnl === TEST_AND_ADD_CFLAGS(flag) dnl === Checks whether $CC supports 'flag' and adds it to AM_CFLAGS on success. AC_DEFUN([TEST_AND_ADD_CFLAGS], [SAVED_CFLAGS="$CFLAGS" CFLAGS="-Werror $1" AC_MSG_CHECKING([whether $CC supports $1]) dnl Note AC_LANG_PROGRAM([]) uses an old-style main definition. AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])], [AC_MSG_RESULT([yes])] dnl Simply append the variable avoiding a dnl compatibility ifdef for AS_VAR_APPEND as this dnl variable shouldn't grow all that large. [AM_CFLAGS="$AM_CFLAGS $1"], [AC_MSG_RESULT([no])]) CFLAGS="$SAVED_CFLAGS"]) TEST_AND_ADD_CFLAGS([-Wall]) TEST_AND_ADD_CFLAGS([-Wdeclaration-after-statement]) TEST_AND_ADD_CFLAGS([-Wextra]) TEST_AND_ADD_CFLAGS([-Wmissing-declarations]) TEST_AND_ADD_CFLAGS([-Wmissing-prototypes]) TEST_AND_ADD_CFLAGS([-Wold-style-definition]) TEST_AND_ADD_CFLAGS([-Wshadow]) TEST_AND_ADD_CFLAGS([-Wunused-but-set-variable]) TEST_AND_ADD_CFLAGS([-Wunused]) TEST_AND_ADD_CFLAGS([-Wvla]) AC_SUBST([AM_CFLAGS]) dnl === CLEAR_LIBVARS([var_pfx]) dnl === Clears _{INCLUDES,LIBS}. AC_DEFUN([CLEAR_LIBVARS], [$1_INCLUDES=""; $1_LIBS=""]) dnl === WITHLIB_OPTION([opt_pfx], [outvar_pfx]) dnl === Defines --with-{include,lib}dir options which set dnl === the variables _{INCLUDES,LIBS}. AC_DEFUN([WITHLIB_OPTION], [AC_ARG_WITH([$1includedir], AS_HELP_STRING([--with-$1includedir=DIR], [use $2 includes from DIR]), $2_INCLUDES="-I$withval") AC_ARG_WITH([$1libdir], AS_HELP_STRING([--with-$1libdir=DIR], [use $2 libraries from DIR]), [$2_LIBS="-L$withval"])]) dnl === LIBCHECK_PROLOGUE([var_pfx]) dnl === Caches the current values of CPPFLAGS/LIBS in SAVED_* then dnl === prepends the current values with _{INCLUDES,LIBS}. AC_DEFUN([LIBCHECK_PROLOGUE], [SAVED_CPPFLAGS=$CPPFLAGS SAVED_LIBS=$LIBS CPPFLAGS="$$1_INCLUDES $CPPFLAGS" LIBS="$$1_LIBS $LIBS"]) dnl === LIBCHECK_EPILOGUE([var_pfx]) dnl === Restores the values of CPPFLAGS/LIBS from SAVED_* and exports dnl === _{INCLUDES,LIBS} with AC_SUBST. AC_DEFUN([LIBCHECK_EPILOGUE], [AC_SUBST($1_LIBS) AC_SUBST($1_INCLUDES) CPPFLAGS=$SAVED_CPPFLAGS LIBS=$SAVED_LIBS]) dnl === Check for pthread support AC_ARG_ENABLE([threading], AS_HELP_STRING([--disable-threading], [Disable detection of thread support]),, [enable_threading=yes]) if test "$enable_threading" = "yes"; then AC_MSG_NOTICE([checking for threading support...]) AX_PTHREAD([AC_DEFINE([WEBP_USE_THREAD], [1], [Undefine this to disable thread support.]) LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC" ], [enable_threading=no]) fi AC_MSG_NOTICE([checking if threading is enabled... ${enable_threading-no}]) dnl === check for OpenGL/GLUT support === CLEAR_LIBVARS([GL]) WITHLIB_OPTION([gl], [GL]) LIBCHECK_PROLOGUE([GL]) glut_cflags="none" glut_ldflags="none" case $host_os in darwin*) # Special case for OSX builds. Append these to give the user a chance to # override with --with-gl* glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL" glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL" ;; esac GLUT_SAVED_CPPFLAGS="$CPPFLAGS" SAVED_IFS="$IFS" IFS="|" for flag in $glut_cflags; do # restore IFS immediately as the autoconf macros may need the default. IFS="$SAVED_IFS" unset ac_cv_header_GL_glut_h unset ac_cv_header_OpenGL_glut_h case $flag in none) ;; *) CPPFLAGS="$flag $CPPFLAGS";; esac AC_CHECK_HEADERS([GL/glut.h GLUT/glut.h OpenGL/glut.h], [glut_headers=yes; test "$flag" = "none" || GL_INCLUDES="$CPPFLAGS"; break]) CPPFLAGS="$GLUT_SAVED_CPPFLAGS" test "$glut_headers" = "yes" && break done IFS="$SAVED_IFS" if test "$glut_headers" = "yes"; then AC_LANG_PUSH([C]) GLUT_SAVED_LDFLAGS="$LDFLAGS" SAVED_IFS="$IFS" IFS="|" for flag in $glut_ldflags; do # restore IFS immediately as the autoconf macros may need the default. IFS="$SAVED_IFS" unset ac_cv_search_glBegin case $flag in none) ;; *) LDFLAGS="$flag $LDFLAGS";; esac # find libGL GL_SAVED_LIBS="$LIBS" AC_SEARCH_LIBS([glBegin], [GL OpenGL]) LIBS="$GL_SAVED_LIBS" # A direct link to libGL may not be necessary on e.g., linux. GLUT_SAVED_LIBS="$LIBS" for lib in "" "-lglut" "-lglut $ac_cv_search_glBegin"; do LIBS="$lib" AC_LINK_IFELSE( [AC_LANG_PROGRAM([ #ifdef __cplusplus # define EXTERN_C extern "C" #else # define EXTERN_C #endif EXTERN_C char glOrtho(); EXTERN_C char glutMainLoop(); ],[ glOrtho(); glutMainLoop(); ]) ], AC_DEFINE(WEBP_HAVE_GL, [1], [Set to 1 if OpenGL is supported]) [glut_support=yes], [] ) if test "$glut_support" = "yes"; then GL_LIBS="$LDFLAGS $lib" break fi done LIBS="$GLUT_SAVED_LIBS" LDFLAGS="$GLUT_SAVED_LDFLAGS" test "$glut_support" = "yes" && break done IFS="$SAVED_IFS" AC_LANG_POP fi LIBCHECK_EPILOGUE([GL]) if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then build_vwebp=yes fi AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"]) dnl === check for PNG support === CLEAR_LIBVARS([PNG]) AC_PATH_PROGS(LIBPNG_CONFIG, [libpng-config libpng15-config libpng14-config libpng12-config]) if test -n "$LIBPNG_CONFIG"; then PNG_INCLUDES=`$LIBPNG_CONFIG --cflags` PNG_PREFIX=`$LIBPNG_CONFIG --prefix` if test "${PNG_PREFIX}/lib" != "/usr/lib" ; then PNG_LIBS="-L${PNG_PREFIX}/lib" fi PNG_LIBS="$PNG_LIBS `$LIBPNG_CONFIG --libs`" fi WITHLIB_OPTION([png], [PNG]) LIBCHECK_PROLOGUE([PNG]) AC_CHECK_HEADER(png.h, AC_SEARCH_LIBS(png_get_libpng_ver, [png], [test "$ac_cv_search_png_get_libpng_ver" = "none required" \ || PNG_LIBS="$PNG_LIBS $ac_cv_search_png_get_libpng_ver" PNG_INCLUDES="$PNG_INCLUDES -DWEBP_HAVE_PNG" AC_DEFINE(WEBP_HAVE_PNG, [1], [Set to 1 if PNG library is installed]) png_support=yes ], [AC_MSG_WARN(Optional png library not found) PNG_LIBS="" PNG_INCLUDES="" ], [$MATH_LIBS]), [AC_MSG_WARN(png library not available - no png.h) PNG_LIBS="" PNG_INCLUDES="" ], ) LIBCHECK_EPILOGUE([PNG]) dnl === check for JPEG support === CLEAR_LIBVARS([JPEG]) WITHLIB_OPTION([jpeg], [JPEG]) LIBCHECK_PROLOGUE([JPEG]) AC_CHECK_HEADER(jpeglib.h, AC_CHECK_LIB(jpeg, jpeg_set_defaults, [JPEG_LIBS="$JPEG_LIBS -ljpeg" JPEG_INCLUDES="$JPEG_INCLUDES -DWEBP_HAVE_JPEG" AC_DEFINE(WEBP_HAVE_JPEG, [1], [Set to 1 if JPEG library is installed]) jpeg_support=yes ], AC_MSG_WARN(Optional jpeg library not found), [$MATH_LIBS]), AC_MSG_WARN(jpeg library not available - no jpeglib.h) ) LIBCHECK_EPILOGUE([JPEG]) dnl === check for TIFF support === CLEAR_LIBVARS([TIFF]) WITHLIB_OPTION([tiff], [TIFF]) LIBCHECK_PROLOGUE([TIFF]) AC_CHECK_HEADER(tiffio.h, AC_CHECK_LIB(tiff, TIFFGetVersion, [TIFF_LIBS="$TIFF_LIBS -ltiff" TIFF_INCLUDES="$TIFF_INCLUDES -DWEBP_HAVE_TIFF" AC_DEFINE(WEBP_HAVE_TIFF, [1], [Set to 1 if TIFF library is installed]) tiff_support=yes ], AC_MSG_WARN(Optional tiff library not found), [$MATH_LIBS]), AC_MSG_WARN(tiff library not available - no tiffio.h) ) LIBCHECK_EPILOGUE([TIFF]) dnl === check for GIF support === CLEAR_LIBVARS([GIF]) WITHLIB_OPTION([gif], [GIF]) LIBCHECK_PROLOGUE([GIF]) AC_CHECK_HEADER(gif_lib.h, AC_CHECK_LIB([gif], [DGifOpenFileHandle], [GIF_LIBS="$GIF_LIBS -lgif" AC_DEFINE(WEBP_HAVE_GIF, [1], [Set to 1 if GIF library is installed]) gif_support=yes ], AC_MSG_WARN(Optional gif library not found), [$MATH_LIBS]), AC_MSG_WARN(gif library not available - no gif_lib.h) ) LIBCHECK_EPILOGUE([GIF]) if test "$gif_support" = "yes" -a \ "$enable_libwebpmux" = "yes"; then build_gif2webp=yes fi AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"]) dnl === check for WIC support === AC_ARG_ENABLE([wic], AS_HELP_STRING([--disable-wic], [Disable Windows Imaging Component (WIC) detection. @<:@default=auto@:>@]),, [enable_wic=yes]) if test "$target_os" = "mingw32" -a "$enable_wic" = "yes"; then AC_CHECK_HEADERS([wincodec.h shlwapi.h windows.h]) if test "$ac_cv_header_wincodec_h" = "yes"; then AC_MSG_CHECKING(for Windows Imaging Component support) SAVED_LIBS=$LIBS LIBS="-lshlwapi -lole32 $LIBS" # match include structure from [cd]webp.c wic_headers=" #define INITGUID #define CINTERFACE #define COBJMACROS #define _WIN32_IE 0x500 #include #include #include " # test for functions from each lib and the GUID is created properly wic_main=" int main(void) { CLSID_WICImagingFactory; CoInitialize(NULL); SHCreateStreamOnFile(NULL, 0, NULL); return 0; } " AC_LANG_PUSH(C) AC_LINK_IFELSE( [AC_LANG_SOURCE([ $wic_headers $wic_main])], [wic_support=yes], [wic_support=no] ) AC_LANG_POP test "$wic_support" = "yes" || LIBS=$SAVED_LIBS AC_MSG_RESULT(${wic_support-no}) fi fi dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP USE_SWAP_16BIT_CSP="" AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified) AC_ARG_ENABLE([swap-16bit-csp], AS_HELP_STRING([--enable-swap-16bit-csp], [Enable byte swap for 16 bit colorspaces])) if test "$enable_swap_16bit_csp" = "yes"; then USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP" fi AC_MSG_RESULT(${enable_swap_16bit_csp-no}) AC_SUBST(USE_SWAP_16BIT_CSP) dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES USE_EXPERIMENTAL_CODE="" AC_MSG_CHECKING(if --enable-experimental option is specified) AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental], [Activate experimental features])) if test "$enable_experimental" = "yes"; then AC_DEFINE(WEBP_EXPERIMENTAL_FEATURES, [1], [Enable experimental code]) USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES" fi AC_MSG_RESULT(${enable_experimental-no}) AC_SUBST(USE_EXPERIMENTAL_CODE) dnl === Check whether libwebpmux should be built AC_MSG_CHECKING(whether libwebpmux is to be built) AC_ARG_ENABLE([libwebpmux], AS_HELP_STRING([--enable-libwebpmux], [Build libwebpmux @<:@default=no@:>@])) AC_MSG_RESULT(${enable_libwebpmux-no}) AM_CONDITIONAL([WANT_MUX], [test "$enable_libwebpmux" = "yes"]) dnl === Check whether libwebpdemux should be built AC_MSG_CHECKING(whether libwebpdemux is to be built) AC_ARG_ENABLE([libwebpdemux], AS_HELP_STRING([--enable-libwebpdemux], [Build libwebpdemux @<:@default=no@:>@])) AC_MSG_RESULT(${enable_libwebpdemux-no}) AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"]) dnl === Check whether decoder library should be built. AC_MSG_CHECKING(whether decoder library is to be built) AC_ARG_ENABLE([libwebpdecoder], AS_HELP_STRING([--enable-libwebpdecoder], [Build libwebpdecoder @<:@default=no@:>@])) AC_MSG_RESULT(${enable_libwebpdecoder-no}) AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"]) dnl ========================= AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \ examples/Makefile src/dec/Makefile \ src/enc/Makefile src/dsp/Makefile \ src/demux/Makefile src/mux/Makefile \ src/utils/Makefile \ src/libwebp.pc src/libwebpdecoder.pc \ src/demux/libwebpdemux.pc src/mux/libwebpmux.pc]) AC_OUTPUT AC_MSG_NOTICE([ WebP Configuration Summary -------------------------- Shared libraries: ${enable_shared} Static libraries: ${enable_static} Threaded decode: ${enable_threading-no} libwebp: yes libwebpdecoder: ${enable_libwebpdecoder-no} libwebpdemux: ${enable_libwebpdemux-no} libwebpmux: ${enable_libwebpmux-no} Tools: cwebp : yes Input format support ==================== JPEG : ${jpeg_support-no} PNG : ${png_support-no} TIFF : ${tiff_support-no} WIC : ${wic_support-no} dwebp : yes Output format support ===================== PNG : ${png_support-no} WIC : ${wic_support-no} GIF support : ${gif_support-no} gif2webp : ${build_gif2webp-no} webpmux : ${enable_libwebpmux-no} vwebp : ${build_vwebp-no} ]) libwebp-0.4.0/doc/0000755000014400001440000000000012255002107010606 5ustar libwebp-0.4.0/doc/README0000644000014400001440000000177612255002107011501 0ustar Generate libwebp Container Spec Docs from Text Source ===================================================== HTML generation requires kramdown [1], easily installed as a rubygem [2]. Rubygems installation should satisfy dependencies automatically. [1]: http://kramdown.rubyforge.org/ [2]: http://rubygems.org/ HTML generation can then be done from the project root: $ kramdown doc/webp-container-spec.txt --template doc/template.html > \ doc/output/webp-container-spec.html kramdown can optionally syntax highlight code blocks, using CodeRay [3], a dependency of kramdown that rubygems will install automatically. The following will apply inline CSS styling; an external stylesheet is not needed. $ kramdown doc/webp-lossless-bitstream-spec.txt --template \ doc/template.html --coderay-css style --coderay-line-numbers ' ' \ --coderay-default-lang c > \ doc/output/webp-lossless-bitstream-spec.html Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired. [3]: http://coderay.rubychan.de/ libwebp-0.4.0/doc/webp-lossless-bitstream-spec.txt0000644000014400001440000012342612255002107017101 0ustar Specification for WebP Lossless Bitstream ========================================= _Jyrki Alakuijala, Ph.D., Google, Inc., 2012-06-19_ Abstract -------- WebP lossless is an image format for lossless compression of ARGB images. The lossless format stores and restores the pixel values exactly, including the color values for zero alpha pixels. The format uses subresolution images, recursively embedded into the format itself, for storing statistical data about the images, such as the used entropy codes, spatial predictors, color space conversion, and color table. LZ77, Huffman coding, and a color cache are used for compression of the bulk data. Decoding speeds faster than PNG have been demonstrated, as well as 25% denser compression than can be achieved using today's PNG format. * TOC placeholder {:toc} Nomenclature ------------ ARGB : A pixel value consisting of alpha, red, green, and blue values. ARGB image : A two-dimensional array containing ARGB pixels. color cache : A small hash-addressed array to store recently used colors, to be able to recall them with shorter codes. color indexing image : A one-dimensional image of colors that can be indexed using a small integer (up to 256 within WebP lossless). color transform image : A two-dimensional subresolution image containing data about correlations of color components. distance mapping : Changes LZ77 distances to have the smallest values for pixels in 2D proximity. entropy image : A two-dimensional subresolution image indicating which entropy coding should be used in a respective square in the image, i.e., each pixel is a meta Huffman code. Huffman code : A classic way to do entropy coding where a smaller number of bits are used for more frequent codes. LZ77 : Dictionary-based sliding window compression algorithm that either emits symbols or describes them as sequences of past symbols. meta Huffman code : A small integer (up to 16 bits) that indexes an element in the meta Huffman table. predictor image : A two-dimensional subresolution image indicating which spatial predictor is used for a particular square in the image. prefix coding : A way to entropy code larger integers that codes a few bits of the integer using an entropy code and codifies the remaining bits raw. This allows for the descriptions of the entropy codes to remain relatively small even when the range of symbols is large. scan-line order : A processing order of pixels, left-to-right, top-to-bottom, starting from the left-hand-top pixel, proceeding to the right. Once a row is completed, continue from the left-hand column of the next row. 1 Introduction -------------- This document describes the compressed data representation of a WebP lossless image. It is intended as a detailed reference for WebP lossless encoder and decoder implementation. In this document, we extensively use C programming language syntax to describe the bitstream, and assume the existence of a function for reading bits, `ReadBits(n)`. The bytes are read in the natural order of the stream containing them, and bits of each byte are read in least-significant-bit-first order. When multiple bits are read at the same time, the integer is constructed from the original data in the original order. The most significant bits of the returned integer are also the most significant bits of the original data. Thus the statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ b = ReadBits(2); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is equivalent with the two statements below: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ b = ReadBits(1); b |= ReadBits(1) << 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We assume that each color component (e.g. alpha, red, blue and green) is represented using an 8-bit byte. We define the corresponding type as uint8. A whole ARGB pixel is represented by a type called uint32, an unsigned integer consisting of 32 bits. In the code showing the behavior of the transformations, alpha value is codified in bits 31..24, red in bits 23..16, green in bits 15..8 and blue in bits 7..0, but implementations of the format are free to use another representation internally. Broadly, a WebP lossless image contains header data, transform information and actual image data. Headers contain width and height of the image. A WebP lossless image can go through four different types of transformation before being entropy encoded. The transform information in the bitstream contains the data required to apply the respective inverse transforms. 2 RIFF Header ------------- The beginning of the header has the RIFF container. This consists of the following 21 bytes: 1. String "RIFF" 2. A little-endian 32 bit value of the block length, the whole size of the block controlled by the RIFF header. Normally this equals the payload size (file size minus 8 bytes: 4 bytes for the 'RIFF' identifier and 4 bytes for storing the value itself). 3. String "WEBP" (RIFF container name). 4. String "VP8L" (chunk tag for lossless encoded image data). 5. A little-endian 32-bit value of the number of bytes in the lossless stream. 6. One byte signature 0x2f. The first 28 bits of the bitstream specify the width and height of the image. Width and height are decoded as 14-bit integers as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int image_width = ReadBits(14) + 1; int image_height = ReadBits(14) + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The 14-bit dynamics for image size limit the maximum size of a WebP lossless image to 16384✕16384 pixels. The alpha_is_used bit is a hint only, and should not impact decoding. It should be set to 0 when all alpha values are 255 in the picture, and 1 otherwise. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int alpha_is_used = ReadBits(1); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The version_number is a 3 bit code that must be discarded by the decoder at this time. Complying encoders write a 3-bit value 0. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int version_number = ReadBits(3); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 Transformations ----------------- Transformations are reversible manipulations of the image data that can reduce the remaining symbolic entropy by modeling spatial and color correlations. Transformations can make the final compression more dense. An image can go through four types of transformation. A 1 bit indicates the presence of a transform. Each transform is allowed to be used only once. The transformations are used only for the main level ARGB image: the subresolution images have no transforms, not even the 0 bit indicating the end-of-transforms. Typically an encoder would use these transforms to reduce the Shannon entropy in the residual image. Also, the transform data can be decided based on entropy minimization. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while (ReadBits(1)) { // Transform present. // Decode transform type. enum TransformType transform_type = ReadBits(2); // Decode transform data. ... } // Decode actual image data (Section 4). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a transform is present then the next two bits specify the transform type. There are four types of transforms. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ enum TransformType { PREDICTOR_TRANSFORM = 0, COLOR_TRANSFORM = 1, SUBTRACT_GREEN = 2, COLOR_INDEXING_TRANSFORM = 3, }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The transform type is followed by the transform data. Transform data contains the information required to apply the inverse transform and depends on the transform type. Next we describe the transform data for different types. ### Predictor Transform The predictor transform can be used to reduce entropy by exploiting the fact that neighboring pixels are often correlated. In the predictor transform, the current pixel value is predicted from the pixels already decoded (in scan-line order) and only the residual value (actual - predicted) is encoded. The _prediction mode_ determines the type of prediction to use. We divide the image into squares and all the pixels in a square use same prediction mode. The first 3 bits of prediction data define the block width and height in number of bits. The number of block columns, `block_xsize`, is used in indexing two-dimensionally. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int size_bits = ReadBits(3) + 2; int block_width = (1 << size_bits); int block_height = (1 << size_bits); #define DIV_ROUND_UP(num, den) ((num) + (den) - 1) / (den)) int block_xsize = DIV_ROUND_UP(image_width, 1 << size_bits); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The transform data contains the prediction mode for each block of the image. All the `block_width * block_height` pixels of a block use same prediction mode. The prediction modes are treated as pixels of an image and encoded using the same techniques described in [Chapter 4](#image-data). For a pixel _x, y_, one can compute the respective filter block address by: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int block_index = (y >> size_bits) * block_xsize + (x >> size_bits); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are 14 different prediction modes. In each prediction mode, the current pixel value is predicted from one or more neighboring pixels whose values are already known. We choose the neighboring pixels (TL, T, TR, and L) of the current pixel (P) as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O O O O O O O O O O O O O O O O O O O O O O O O O O TL T TR O O O O O O O O L P X X X X X X X X X X X X X X X X X X X X X X X X X X X ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where TL means top-left, T top, TR top-right, L left pixel. At the time of predicting a value for P, all pixels O, TL, T, TR and L have been already processed, and pixel P and all pixels X are unknown. Given the above neighboring pixels, the different prediction modes are defined as follows. | Mode | Predicted value of each channel of the current pixel | | ------ | ------------------------------------------------------- | | 0 | 0xff000000 (represents solid black color in ARGB) | | 1 | L | | 2 | T | | 3 | TR | | 4 | TL | | 5 | Average2(Average2(L, TR), T) | | 6 | Average2(L, TL) | | 7 | Average2(L, T) | | 8 | Average2(TL, T) | | 9 | Average2(T, TR) | | 10 | Average2(Average2(L, TL), Average2(T, TR)) | | 11 | Select(L, T, TL) | | 12 | ClampAddSubtractFull(L, T, TL) | | 13 | ClampAddSubtractHalf(Average2(L, T), TL) | `Average2` is defined as follows for each ARGB component: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint8 Average2(uint8 a, uint8 b) { return (a + b) / 2; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Select predictor is defined as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uint32 Select(uint32 L, uint32 T, uint32 TL) { // L = left pixel, T = top pixel, TL = top left pixel. // ARGB component estimates for prediction. int pAlpha = ALPHA(L) + ALPHA(T) - ALPHA(TL); int pRed = RED(L) + RED(T) - RED(TL); int pGreen = GREEN(L) + GREEN(T) - GREEN(TL); int pBlue = BLUE(L) + BLUE(T) - BLUE(TL); // Manhattan distances to estimates for left and top pixels. int pL = abs(pAlpha - ALPHA(L)) + abs(pRed - RED(L)) + abs(pGreen - GREEN(L)) + abs(pBlue - BLUE(L)); int pT = abs(pAlpha - ALPHA(T)) + abs(pRed - RED(T)) + abs(pGreen - GREEN(T)) + abs(pBlue - BLUE(T)); // Return either left or top, the one closer to the prediction. if (pL <= pT) { return L; } else { return T; } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The functions `ClampAddSubtractFull` and `ClampAddSubtractHalf` are performed for each ARGB component as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Clamp the input value between 0 and 255. int Clamp(int a) { return (a < 0) ? 0 : (a > 255) ? 255 : a; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int ClampAddSubtractFull(int a, int b, int c) { return Clamp(a + b - c); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int ClampAddSubtractHalf(int a, int b) { return Clamp(a + (a - b) / 2); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are special handling rules for some border pixels. If there is a prediction transform, regardless of the mode \[0..13\] for these pixels, the predicted value for the left-topmost pixel of the image is 0xff000000, L-pixel for all pixels on the top row, and T-pixel for all pixels on the leftmost column. Addressing the TR-pixel for pixels on the rightmost column is exceptional. The pixels on the rightmost column are predicted by using the modes \[0..13\] just like pixels not on border, but by using the leftmost pixel on the same row as the current TR-pixel. The TR-pixel offset in memory is the same for border and non-border pixels. ### Color Transform The goal of the color transform is to decorrelate the R, G and B values of each pixel. Color transform keeps the green (G) value as it is, transforms red (R) based on green and transforms blue (B) based on green and then based on red. As is the case for the predictor transform, first the image is divided into blocks and the same transform mode is used for all the pixels in a block. For each block there are three types of color transform elements. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ typedef struct { uint8 green_to_red; uint8 green_to_blue; uint8 red_to_blue; } ColorTransformElement; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The actual color transformation is done by defining a color transform delta. The color transform delta depends on the `ColorTransformElement`, which is the same for all the pixels in a particular block. The delta is added during color transform. The inverse color transform then is just subtracting those deltas. The color transform function is defined as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void ColorTransform(uint8 red, uint8 blue, uint8 green, ColorTransformElement *trans, uint8 *new_red, uint8 *new_blue) { // Transformed values of red and blue components uint32 tmp_red = red; uint32 tmp_blue = blue; // Applying transform is just adding the transform deltas tmp_red += ColorTransformDelta(trans->green_to_red, green); tmp_blue += ColorTransformDelta(trans->green_to_blue, green); tmp_blue += ColorTransformDelta(trans->red_to_blue, red); *new_red = tmp_red & 0xff; *new_blue = tmp_blue & 0xff; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `ColorTransformDelta` is computed using a signed 8-bit integer representing a 3.5-fixed-point number, and a signed 8-bit RGB color channel (c) \[-128..127\] and is defined as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int8 ColorTransformDelta(int8 t, int8 c) { return (t * c) >> 5; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The multiplication is to be done using more precision (with at least 16-bit dynamics). The sign extension property of the shift operation does not matter here: only the lowest 8 bits are used from the result, and there the sign extension shifting and unsigned shifting are consistent with each other. Now we describe the contents of color transform data so that decoding can apply the inverse color transform and recover the original red and blue values. The first 3 bits of the color transform data contain the width and height of the image block in number of bits, just like the predictor transform: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int size_bits = ReadBits(3) + 2; int block_width = 1 << size_bits; int block_height = 1 << size_bits; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The remaining part of the color transform data contains `ColorTransformElement` instances corresponding to each block of the image. `ColorTransformElement` instances are treated as pixels of an image and encoded using the methods described in [Chapter 4](#image-data). During decoding, `ColorTransformElement` instances of the blocks are decoded and the inverse color transform is applied on the ARGB values of the pixels. As mentioned earlier, that inverse color transform is just subtracting `ColorTransformElement` values from the red and blue channels. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void InverseTransform(uint8 red, uint8 green, uint8 blue, ColorTransformElement *p, uint8 *new_red, uint8 *new_blue) { // Applying inverse transform is just subtracting the // color transform deltas red -= ColorTransformDelta(p->green_to_red_, green); blue -= ColorTransformDelta(p->green_to_blue_, green); blue -= ColorTransformDelta(p->red_to_blue_, red & 0xff); *new_red = red & 0xff; *new_blue = blue & 0xff; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ### Subtract Green Transform The subtract green transform subtracts green values from red and blue values of each pixel. When this transform is present, the decoder needs to add the green value to both red and blue. There is no data associated with this transform. The decoder applies the inverse transform as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void AddGreenToBlueAndRed(uint8 green, uint8 *red, uint8 *blue) { *red = (*red + green) & 0xff; *blue = (*blue + green) & 0xff; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This transform is redundant as it can be modeled using the color transform, but it is still often useful. Since it can extend the dynamics of the color transform and there is no additional data here, the subtract green transform can be coded using fewer bits than a full-blown color transform. ### Color Indexing Transform If there are not many unique pixel values, it may be more efficient to create a color index array and replace the pixel values by the array's indices. The color indexing transform achieves this. (In the context of WebP lossless, we specifically do not call this a palette transform because a similar but more dynamic concept exists in WebP lossless encoding: color cache.) The color indexing transform checks for the number of unique ARGB values in the image. If that number is below a threshold (256), it creates an array of those ARGB values, which is then used to replace the pixel values with the corresponding index: the green channel of the pixels are replaced with the index; all alpha values are set to 255; all red and blue values to 0. The transform data contains color table size and the entries in the color table. The decoder reads the color indexing transform data as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 8 bit value for color table size int color_table_size = ReadBits(8) + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The color table is stored using the image storage format itself. The color table can be obtained by reading an image, without the RIFF header, image size, and transforms, assuming a height of one pixel and a width of `color_table_size`. The color table is always subtraction-coded to reduce image entropy. The deltas of palette colors contain typically much less entropy than the colors themselves, leading to significant savings for smaller images. In decoding, every final color in the color table can be obtained by adding the previous color component values by each ARGB component separately, and storing the least significant 8 bits of the result. The inverse transform for the image is simply replacing the pixel values (which are indices to the color table) with the actual color table values. The indexing is done based on the green component of the ARGB color. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Inverse transform argb = color_table[GREEN(argb)]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the color table is small (equal to or less than 16 colors), several pixels are bundled into a single pixel. The pixel bundling packs several (2, 4, or 8) pixels into a single pixel, reducing the image width respectively. Pixel bundling allows for a more efficient joint distribution entropy coding of neighboring pixels, and gives some arithmetic coding-like benefits to the entropy code, but it can only be used when there are a small number of unique values. `color_table_size` specifies how many pixels are combined together: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int width_bits; if (color_table_size <= 2) { width_bits = 3; } else if (color_table_size <= 4) { width_bits = 2; } else if (color_table_size <= 16) { width_bits = 1; } else { width_bits = 0; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `width_bits` has a value of 0, 1, 2 or 3. A value of 0 indicates no pixel bundling to be done for the image. A value of 1 indicates that two pixels are combined together, and each pixel has a range of \[0..15\]. A value of 2 indicates that four pixels are combined together, and each pixel has a range of \[0..3\]. A value of 3 indicates that eight pixels are combined together and each pixel has a range of \[0..1\], i.e., a binary value. The values are packed into the green component as follows: * `width_bits` = 1: for every x value where x ≡ 0 (mod 2), a green value at x is positioned into the 4 least-significant bits of the green value at x / 2, a green value at x + 1 is positioned into the 4 most-significant bits of the green value at x / 2. * `width_bits` = 2: for every x value where x ≡ 0 (mod 4), a green value at x is positioned into the 2 least-significant bits of the green value at x / 4, green values at x + 1 to x + 3 in order to the more significant bits of the green value at x / 4. * `width_bits` = 3: for every x value where x ≡ 0 (mod 8), a green value at x is positioned into the least-significant bit of the green value at x / 8, green values at x + 1 to x + 7 in order to the more significant bits of the green value at x / 8. 4 Image Data ------------ Image data is an array of pixel values in scan-line order. ### 4.1 Roles of Image Data We use image data in five different roles: 1. ARGB image: Stores the actual pixels of the image. 1. Entropy image: Stores the [meta Huffman codes](#decoding-of-meta-huffman-codes). The red and green components of a pixel define the meta Huffman code used in a particular block of the ARGB image. 1. Predictor image: Stores the metadata for [Predictor Transform](#predictor-transform). The green component of a pixel defines which of the 14 predictors is used within a particular block of the ARGB image. 1. Color transform image. It is created by `ColorTransformElement` values (defined in [Color Transform](#color-transform)) for different blocks of the image. Each `ColorTransformElement` `'cte'` is treated as a pixel whose alpha component is `255`, red component is `cte.red_to_blue`, green component is `cte.green_to_blue` and blue component is `cte.green_to_red`. 1. Color indexing image: An array of of size `color_table_size` (up to 256 ARGB values) storing the metadata for the [Color Indexing Transform](#color-indexing-transform). This is stored as an image of width `color_table_size` and height `1`. ### 4.2 Encoding of Image data The encoding of image data is independent of its role. The image is first divided into a set of fixed-size blocks (typically 16x16 blocks). Each of these blocks are modeled using their own entropy codes. Also, several blocks may share the same entropy codes. **Rationale:** Storing an entropy code incurs a cost. This cost can be minimized if statistically similar blocks share an entropy code, thereby storing that code only once. For example, an encoder can find similar blocks by clustering them using their statistical properties, or by repeatedly joining a pair of randomly selected clusters when it reduces the overall amount of bits needed to encode the image. Each pixel is encoded using one of the three possible methods: 1. Huffman coded literal: each channel (green, red, blue and alpha) is entropy-coded independently; 2. LZ77 backward reference: a sequence of pixels are copied from elsewhere in the image; or 3. Color cache code: using a short multiplicative hash code (color cache index) of a recently seen color. The following sub-sections describe each of these in detail. #### 4.2.1 Huffman Coded Literals The pixel is stored as Huffman coded values of green, red, blue and alpha (in that order). See [this section](#decoding-entropy-coded-image-data) for details. #### 4.2.2 LZ77 Backward Reference Backward references are tuples of _length_ and _distance code_: * Length indicates how many pixels in scan-line order are to be copied. * Distance code is a number indicating the position of a previously seen pixel, from which the pixels are to be copied. The exact mapping is described [below](#distance-mapping). The length and distance values are stored using **LZ77 prefix coding**. LZ77 prefix coding divides large integer values into two parts: the _prefix code_ and the _extra bits_: the prefix code is stored using an entropy code, while the extra bits are stored as they are (without an entropy code). **Rationale**: This approach reduces the storage requirement for the entropy code. Also, large values are usually rare, and so extra bits would be used for very few values in the image. Thus, this approach results in a better compression overall. The following table denotes the prefix codes and extra bits used for storing different range of values. Note: The maximum backward reference length is limited to 4096. Hence, only the first 24 prefix codes (with the respective extra bits) are meaningful for length values. For distance values, however, all the 40 prefix codes are valid. | Value range | Prefix code | Extra bits | | --------------- | ----------- | ---------- | | 1 | 0 | 0 | | 2 | 1 | 0 | | 3 | 2 | 0 | | 4 | 3 | 0 | | 5..6 | 4 | 1 | | 7..8 | 5 | 1 | | 9..12 | 6 | 2 | | 13..16 | 7 | 2 | | ... | ... | ... | | 3072..4096 | 23 | 10 | | ... | ... | ... | | 524289..786432 | 38 | 18 | | 786433..1048576 | 39 | 18 | The pseudocode to obtain a (length or distance) value from the prefix code is as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (prefix_code < 4) { return prefix_code + 1; } int extra_bits = (prefix_code - 2) >> 1; int offset = (2 + (prefix_code & 1)) << extra_bits; return offset + ReadBits(extra_bits) + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Distance Mapping:** {:#distance-mapping} As noted previously, distance code is a number indicating the position of a previously seen pixel, from which the pixels are to be copied. This sub-section defines the mapping between a distance code and the position of a previous pixel. The distance codes larger than 120 denote the pixel-distance in scan-line order, offset by 120. The smallest distance codes \[1..120\] are special, and are reserved for a close neighborhood of the current pixel. This neighborhood consists of 120 pixels: * Pixels that are 1 to 7 rows above the current pixel, and are up to 8 columns to the left or up to 7 columns to the right of the current pixel. \[Total such pixels = `7 * (8 + 1 + 7) = 112`\]. * Pixels that are in same row as the current pixel, and are up to 8 columns to the left of the current pixel. \[`8` such pixels\]. The mapping between distance code `i` and the neighboring pixel offset `(xi, yi)` is as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), (-1, 2), (2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), (1, 3), (-1, 3), (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), (-3, 2), (0, 4), (4, 0), (1, 4), (-1, 4), (4, 1), (-4, 1), (3, 3), (-3, 3), (2, 4), (-2, 4), (4, 2), (-4, 2), (0, 5), (3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0), (1, 5), (-1, 5), (5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2), (4, 4), (-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0), (1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), (-6, 2), (4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), (6, 3), (-6, 3), (0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), (-5, 5), (7, 1), (-7, 1), (4, 6), (-4, 6), (6, 4), (-6, 4), (2, 7), (-2, 7), (7, 2), (-7, 2), (3, 7), (-3, 7), (7, 3), (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5), (8, 0), (4, 7), (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6), (-6, 6), (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7), (-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For example, distance code `1` indicates offset of `(0, 1)` for the neighboring pixel, that is, the pixel above the current pixel (0-pixel difference in X-direction and 1 pixel difference in Y-direction). Similarly, distance code `3` indicates left-top pixel. The decoder can convert a distances code 'i' to a scan-line order distance 'dist' as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (xi, yi) = distance_map[i] dist = x + y * xsize if (dist < 1) { dist = 1 } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where 'distance_map' is the mapping noted above and `xsize` is the width of the image in pixels. #### 4.2.3 Color Cache Coding Color cache stores a set of colors that have been recently used in the image. **Rationale:** This way, the recently used colors can sometimes be referred to more efficiently than emitting them using other two methods (described in [4.2.1](#huffman-coded-literals) and [4.2.2](#lz77-backward-reference)). Color cache codes are stored as follows. First, there is a 1-bit value that indicates if the color cache is used. If this bit is 0, no color cache codes exist, and they are not transmitted in the Huffman code that decodes the green symbols and the length prefix codes. However, if this bit is 1, the color cache size is read next: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int color_cache_code_bits = ReadBits(4); int color_cache_size = 1 << color_cache_code_bits; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `color_cache_code_bits` defines the size of the color_cache by (1 << `color_cache_code_bits`). The range of allowed values for `color_cache_code_bits` is \[1..11\]. Compliant decoders must indicate a corrupted bitstream for other values. A color cache is an array of size `color_cache_size`. Each entry stores one ARGB color. Colors are looked up by indexing them by (0x1e35a7bd * `color`) >> (32 - `color_cache_code_bits`). Only one lookup is done in a color cache; there is no conflict resolution. In the beginning of decoding or encoding of an image, all entries in all color cache values are set to zero. The color cache code is converted to this color at decoding time. The state of the color cache is maintained by inserting every pixel, be it produced by backward referencing or as literals, into the cache in the order they appear in the stream. 5 Entropy Code -------------- ### 5.1 Overview Most of the data is coded using [canonical Huffman code][canonical_huff]. Hence, the codes are transmitted by sending the _Huffman code lengths_, as opposed to the actual _Huffman codes_. In particular, the format uses **spatially-variant Huffman coding**. In other words, different blocks of the image can potentially use different entropy codes. **Rationale**: Different areas of the image may have different characteristics. So, allowing them to use different entropy codes provides more flexibility and potentially a better compression. ### 5.2 Details The encoded image data consists of two parts: 1. Meta Huffman codes 1. Entropy-coded image data #### 5.2.1 Decoding of Meta Huffman Codes As noted earlier, the format allows the use of different Huffman codes for different blocks of the image. _Meta Huffman codes_ are indexes identifying which Huffman codes to use in different parts of the image. Meta Huffman codes may be used _only_ when the image is being used in the [role](#roles-of-image-data) of an _ARGB image_. There are two possibilities for the meta Huffman codes, indicated by a 1-bit value: * If this bit is zero, there is only one meta Huffman code used everywhere in the image. No more data is stored. * If this bit is one, the image uses multiple meta Huffman codes. These meta Huffman codes are stored as an _entropy image_ (described below). **Entropy image:** The entropy image defines which Huffman codes are used in different parts of the image, as described below. The first 3-bits contain the `huffman_bits` value. The dimensions of the entropy image are derived from 'huffman_bits'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int huffman_bits = ReadBits(3) + 2; int huffman_xsize = DIV_ROUND_UP(xsize, 1 << huffman_bits); int huffman_ysize = DIV_ROUND_UP(ysize, 1 << huffman_bits); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where `DIV_ROUND_UP` is as defined [earlier](#predictor-transform). Next bits contain an entropy image of width `huffman_xsize` and height `huffman_ysize`. **Interpretation of Meta Huffman Codes:** For any given pixel (x, y), there is a set of five Huffman codes associated with it. These codes are (in bitstream order): * **Huffman code #1**: used for green channel, backward-reference length and color cache * **Huffman code #2, #3 and #4**: used for red, blue and alpha channels respectively. * **Huffman code #5**: used for backward-reference distance. From here on, we refer to this set as a **Huffman code group**. The number of Huffman code groups in the ARGB image can be obtained by finding the _largest meta Huffman code_ from the entropy image: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int num_huff_groups = max(entropy image) + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where `max(entropy image)` indicates the largest Huffman code stored in the entropy image. As each Huffman code groups contains five Huffman codes, the total number of Huffman codes is: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int num_huff_codes = 5 * num_huff_groups; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Given a pixel (x, y) in the ARGB image, we can obtain the corresponding Huffman codes to be used as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int position = (y >> huffman_bits) * huffman_xsize + (x >> huffman_bits); int meta_huff_code = (entropy_image[pos] >> 8) & 0xffff; HuffmanCodeGroup huff_group = huffman_code_groups[meta_huff_code]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where, we have assumed the existence of `HuffmanCodeGroup` structure, which represents a set of five Huffman codes. Also, `huffman_code_groups` is an array of `HuffmanCodeGroup` (of size `num_huff_groups`). The decoder then uses Huffman code group `huff_group` to decode the pixel (x, y) as explained in the [next section](#decoding-entropy-coded-image-data). #### 5.2.2 Decoding Entropy-coded Image Data For the current position (x, y) in the image, the decoder first identifies the corresponding Huffman code group (as explained in the last section). Given the Huffman code group, the pixel is read and decoded as follows: Read next symbol S from the bitstream using Huffman code #1. \[See [next section](#decoding-the-code-lengths) for details on decoding the Huffman code lengths\]. Note that S is any integer in the range `0` to `(256 + 24 + ` [`color_cache_size`](#color-cache-code)`- 1)`. The interpretation of S depends on its value: 1. if S < 256 1. Use S as the green component 1. Read red from the bitstream using Huffman code #2 1. Read blue from the bitstream using Huffman code #3 1. Read alpha from the bitstream using Huffman code #4 1. if S < 256 + 24 1. Use S - 256 as a length prefix code 1. Read extra bits for length from the bitstream 1. Determine backward-reference length L from length prefix code and the extra bits read. 1. Read distance prefix code from the bitstream using Huffman code #5 1. Read extra bits for distance from the bitstream 1. Determine backward-reference distance D from distance prefix code and the extra bits read. 1. Copy the L pixels (in scan-line order) from the sequence of pixels prior to them by D pixels. 1. if S >= 256 + 24 1. Use S - (256 + 24) as the index into the color cache. 1. Get ARGB color from the color cache at that index. **Decoding the Code Lengths:** {:#decoding-the-code-lengths} This section describes the details about reading a symbol from the bitstream by decoding the Huffman code length. The Huffman code lengths can be coded in two ways. The method used is specified by a 1-bit value. * If this bit is 1, it is a _simple code length code_, and * If this bit is 0, it is a _normal code length code_. **(i) Simple Code Length Code:** This variant is used in the special case when only 1 or 2 Huffman code lengths are non-zero, and are in the range of \[0, 255\]. All other Huffman code lengths are implicitly zeros. The first bit indicates the number of non-zero code lengths: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int num_code_lengths = ReadBits(1) + 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The first code length is stored either using a 1-bit code for values of 0 and 1, or using an 8-bit code for values in range \[0, 255\]. The second code length, when present, is coded as an 8-bit code. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int is_first_8bits = ReadBits(1); code_lengths[0] = ReadBits(1 + 7 * is_first_8bits); if (num_code_lengths == 2) { code_lengths[1] = ReadBits(8); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Note:** Another special case is when _all_ Huffman code lengths are _zeros_ (an empty Huffman code). For example, a Huffman code for distance can be empty if there are no backward references. Similarly, Huffman codes for alpha, red, and blue can be empty if all pixels within the same meta Huffman code are produced using the color cache. However, this case doesn't need a special handling, as empty Huffman codes can be coded as those containing a single symbol `0`. **(ii) Normal Code Length Code:** The code lengths of a Huffman code are read as follows: `num_code_lengths` specifies the number of code lengths; the rest of the code lengths (according to the order in `kCodeLengthCodeOrder`) are zeros. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int kCodeLengthCodes = 19; int kCodeLengthCodeOrder[kCodeLengthCodes] = { 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; int code_lengths[kCodeLengthCodes] = { 0 }; // All zeros. int num_code_lengths = 4 + ReadBits(4); for (i = 0; i < num_code_lengths; ++i) { code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Code length code \[0..15\] indicates literal code lengths. * Value 0 means no symbols have been coded. * Values \[1..15\] indicate the bit length of the respective code. * Code 16 repeats the previous non-zero value \[3..6\] times, i.e., 3 + `ReadBits(2)` times. If code 16 is used before a non-zero value has been emitted, a value of 8 is repeated. * Code 17 emits a streak of zeros \[3..10\], i.e., 3 + `ReadBits(3)` times. * Code 18 emits a streak of zeros of length \[11..138\], i.e., 11 + `ReadBits(7)` times. 6 Overall Structure of the Format --------------------------------- Below is a view into the format in Backus-Naur form. It does not cover all details. End-of-image (EOI) is only implicitly coded into the number of pixels (xsize * ysize). #### Basic Structure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ::= ::= ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #### Structure of Transforms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ::= (1-bit value 1; ) | 1-bit value 0 ::= | | | ::= 2-bit value 0; ::= 3-bit sub-pixel code ; ::= 2-bit value 1; ::= 3-bit sub-pixel code ; ::= 2-bit value 2 ::= 2-bit value 3; ::= 8-bit color count; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #### Structure of the Image Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ::= ::= ::= 1-bit value 0 | (1-bit value 1; ) ::= 3-bit subsample value; ::= 1 bit value 0 | (1-bit value 1; 4-bit value for color cache size) ::= | ::= See "Interpretation of Meta Huffman codes" to understand what each of these five Huffman codes are for. ::= | ::= see "Simple code length code" for details ::= ; encoded code lengths ::= see section "Normal code length code" ::= (( | | ) ) | "" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A possible example sequence: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1-bit value 1 1-bit value 11-bit value 0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code libwebp-0.4.0/doc/webp-container-spec.txt0000644000014400001440000010313112255002107015213 0ustar WebP Container Specification ============================ * TOC placeholder {:toc} Introduction ------------ WebP is an image format that uses either (i) the VP8 key frame encoding to compress image data in a lossy way, or (ii) the WebP lossless encoding (and possibly other encodings in the future). These encoding schemes should make it more efficient than currently used formats. It is optimized for fast image transfer over the network (e.g., for websites). The WebP format has feature parity (color profile, metadata, animation etc) with other formats as well. This document describes the structure of a WebP file. The WebP container (i.e., RIFF container for WebP) allows feature support over and above the basic use case of WebP (i.e., a file containing a single image encoded as a VP8 key frame). The WebP container provides additional support for: * **Lossless compression.** An image can be losslessly compressed, using the WebP Lossless Format. * **Metadata.** An image may have metadata stored in EXIF or XMP formats. * **Transparency.** An image may have transparency, i.e., an alpha channel. * **Color Profile.** An image may have an embedded ICC profile as described by the [International Color Consortium][iccspec]. * **Animation.** An image may have multiple frames with pauses between them, making it an animation. * **Image Fragmentation.** A single bitstream in WebP has an inherent limitation for width or height of 2^14 pixels, and, when using VP8, a 512 KiB limit on the size of the first compressed partition. To support larger images, the format supports images that are composed of multiple fragments, each encoded as a separate bitstream. All fragments logically form a single image: they have common metadata, color profile, etc. Image fragmentation may also improve efficiency for larger images, e.g., grass can be encoded differently than sky. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119][]. **Note:** Out of the features mentioned above, lossy compression, lossless compression, transparency, metadata, color profile and animation are finalized and are to be considered stable. On the other hand, image fragmentation is experimental as of now, and is open to discussion, feedback and comments. The same is indicated using annotation "_status: experimental_" in the relevant sections of this document. Terminology & Basics ------------------------ A WebP file contains either a still image (i.e., an encoded matrix of pixels) or an [animation](#animation). Optionally, it can also contain transparency information, color profile and metadata. In case we need to refer only to the matrix of pixels, we will call it the _canvas_ of the image. Below are additional terms used throughout this document: _Reader/Writer_ : Code that reads WebP files is referred to as a _reader_, while code that writes them is referred to as a _writer_. _uint16_ : A 16-bit, little-endian, unsigned integer. _uint24_ : A 24-bit, little-endian, unsigned integer. _uint32_ : A 32-bit, little-endian, unsigned integer. _FourCC_ : A _FourCC_ (four-character code) is a _uint32_ created by concatenating four ASCII characters in little-endian order. _1-based_ : An unsigned integer field storing values offset by `-1`. e.g., Such a field would store value _25_ as _24_. RIFF file format ---------------- The WebP file format is based on the RIFF (resource interchange file format) document format. The basic element of a RIFF file is a _chunk_. It consists of: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Chunk FourCC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Chunk Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Chunk Payload | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Chunk FourCC: 32 bits : ASCII four-character code used for chunk identification. Chunk Size: 32 bits (_uint32_) : The size of the chunk not including this field, the chunk identifier or padding. Chunk Payload: _Chunk Size_ bytes : The data payload. If _Chunk Size_ is odd, a single padding byte -- that SHOULD be `0` -- is added. _ChunkHeader('ABCD')_ : This is used to describe the _FourCC_ and _Chunk Size_ header of individual chunks, where 'ABCD' is the FourCC for the chunk. This element's size is 8 bytes. **Note:** RIFF has a convention that all-uppercase chunk FourCCs are standard chunks that apply to any RIFF file format, while FourCCs specific to a file format are all lowercase. WebP does not follow this convention. WebP file header ---------------- 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 'R' | 'I' | 'F' | 'F' | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | File Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 'W' | 'E' | 'B' | 'P' | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 'RIFF': 32 bits : The ASCII characters 'R' 'I' 'F' 'F'. File Size: 32 bits (_uint32_) : The size of the file in bytes starting at offset 8. The maximum value of this field is 2^32 minus 10 bytes and thus the size of the whole file is at most 4GiB minus 2 bytes. 'WEBP': 32 bits : The ASCII characters 'W' 'E' 'B' 'P'. A WebP file MUST begin with a RIFF header with the FourCC 'WEBP'. The file size in the header is the total size of the chunks that follow plus `4` bytes for the 'WEBP' FourCC. The file SHOULD NOT contain anything after it. As the size of any chunk is even, the size given by the RIFF header is also even. The contents of individual chunks will be described in the following sections. Simple file format (lossy) -------------------------- This layout SHOULD be used if the image requires _lossy_ encoding and does not require transparency or other advanced features provided by the extended format. Files with this layout are smaller and supported by older software. Simple WebP (lossy) file format: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | WebP file header (12 bytes) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | VP8 chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ VP8 chunk: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('VP8 ') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | VP8 data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ VP8 data: _Chunk Size_ bytes : VP8 bitstream data. The VP8 bitstream format specification can be found at [VP8 Data Format and Decoding Guide][vp8spec]. Note that the VP8 frame header contains the VP8 frame width and height. That is assumed to be the width and height of the canvas. The VP8 specification describes how to decode the image into Y'CbCr format. To convert to RGB, Rec. 601 SHOULD be used. Simple file format (lossless) ----------------------------- **Note:** Older readers may not support files using the lossless format. This layout SHOULD be used if the image requires _lossless_ encoding (with an optional transparency channel) and does not require advanced features provided by the extended format. Simple WebP (lossless) file format: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | WebP file header (12 bytes) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | VP8L chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ VP8L chunk: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('VP8L') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | VP8L data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ VP8L data: _Chunk Size_ bytes : VP8L bitstream data. The current specification of the VP8L bitstream can be found at [WebP Lossless Bitstream Format][webpllspec]. Note that the VP8L header contains the VP8L image width and height. That is assumed to be the width and height of the canvas. Extended file format -------------------- **Note:** Older readers may not support files using the extended format. An extended format file consists of: * A 'VP8X' chunk with information about features used in the file. * An optional 'ICCP' chunk with color profile. * An optional 'ANIM' chunk with animation control data. * Image data. * An optional 'EXIF' chunk with EXIF metadata. * An optional 'XMP ' chunk with XMP metadata. * An optional list of [unknown chunks](#unknown-chunks). _\[status: experimental\]_ For a _still image_, the _image data_ consists of a single frame, whereas for an _animated image_, it consists of multiple frames. More details about frames can be found in the [Animation](#animation) section. Moreover, each frame can be fragmented or non-fragmented, as will be described in the [Extended WebP file header](#extended_header) section. More details about fragments can be found in the [Fragments](#fragments) section. All chunks SHOULD be placed in the same order as listed above. If a chunk appears in the wrong place, the file is invalid, but readers MAY parse the file, ignoring the chunks that come too late. **Rationale:** Setting the order of chunks should allow quicker file parsing. For example, if an 'ALPH' chunk does not appear in its required position, a decoder can choose to stop searching for it. The rule of ignoring late chunks should make programs that need to do a full search give the same results as the ones stopping early. Extended WebP file header: {:#extended_header} 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | WebP file header (12 bytes) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('VP8X') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Rsv|I|L|E|X|A|F| Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Canvas Width Minus One | ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ... Canvas Height Minus One | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Reserved (Rsv): 2 bits : SHOULD be `0`. ICC profile (I): 1 bit : Set if the file contains an ICC profile. Alpha (L): 1 bit : Set if any of the frames of the image contain transparency information ("alpha"). EXIF metadata (E): 1 bit : Set if the file contains EXIF metadata. XMP metadata (X): 1 bit : Set if the file contains XMP metadata. Animation (A): 1 bit : Set if this is an animated image. Data in 'ANIM' and 'ANMF' chunks should be used to control the animation. Image Fragmentation (F): 1 bit _\[status: experimental\]_ : Set if any of the frames in the image are represented by fragments. Reserved: 24 bits : SHOULD be `0`. Canvas Width Minus One: 24 bits : _1-based_ width of the canvas in pixels. The actual canvas width is '1 + Canvas Width Minus One' Canvas Height Minus One: 24 bits : _1-based_ height of the canvas in pixels. The actual canvas height is '1 + Canvas Height Minus One' The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`. Future specifications MAY add more fields. ### Chunks #### Animation An animation is controlled by ANIM and ANMF chunks. ANIM Chunk: {:#anim_chunk} For an animated image, this chunk contains the _global parameters_ of the animation. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('ANIM') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Background Color | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Loop Count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Background Color: 32 bits (_uint32_) : The default background color of the canvas in \[Blue, Green, Red, Alpha\] byte order. This color MAY be used to fill the unused space on the canvas around the frames, as well as the transparent pixels of the first frame. Background color is also used when disposal method is `1`. **Note**: * Background color MAY contain a transparency value (alpha), even if the _Alpha_ flag in [VP8X chunk](#extended_header) is unset. * Viewer applications SHOULD treat the background color value as a hint, and are not required to use it. Loop Count: 16 bits (_uint16_) : The number of times to loop the animation. `0` means infinitely. This chunk MUST appear if the _Animation_ flag in the VP8X chunk is set. If the _Animation_ flag is not set and this chunk is present, it SHOULD be ignored. ANMF chunk: For animated images, this chunk contains information about a _single_ frame. If the _Animation flag_ is not set, then this chunk SHOULD NOT be present. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('ANMF') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frame X | ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ... Frame Y | Frame Width Minus One ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ... | Frame Height Minus One | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frame Duration | Reserved |B|D| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frame Data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Frame X: 24 bits (_uint24_) : The X coordinate of the upper left corner of the frame is `Frame X * 2` Frame Y: 24 bits (_uint24_) : The Y coordinate of the upper left corner of the frame is `Frame Y * 2` Frame Width Minus One: 24 bits (_uint24_) : The _1-based_ width of the frame. The frame width is `1 + Frame Width Minus One` Frame Height Minus One: 24 bits (_uint24_) : The _1-based_ height of the frame. The frame height is `1 + Frame Height Minus One` Frame Duration: 24 bits (_uint24_) : The time to wait before displaying the next frame, in 1 millisecond units. In particular, frame duration of 0 is useful when one wants to update multiple areas of the canvas at once during the animation. Reserved: 6 bits : SHOULD be 0. Blending method (B): 1 bit : Indicates how transparent pixels of _the current frame_ are to be blended with corresponding pixels of the previous canvas: * `0`: Use alpha blending. After disposing of the previous frame, render the current frame on the canvas using [alpha-blending](#alpha-blending). If the current frame does not have an alpha channel, assume alpha value of 255, effectively replacing the rectangle. * `1`: Do not blend. After disposing of the previous frame, render the current frame on the canvas by overwriting the rectangle covered by the current frame. Disposal method (D): 1 bit : Indicates how _the current frame_ is to be treated after it has been displayed (before rendering the next frame) on the canvas: * `0`: Do not dispose. Leave the canvas as is. * `1`: Dispose to background color. Fill the _rectangle_ on the canvas covered by the _current frame_ with background color specified in the [ANIM chunk](#anim_chunk). **Notes**: * The frame disposal only applies to the _frame rectangle_, that is, the rectangle defined by _Frame X_, _Frame Y_, _frame width_ and _frame height_. It may or may not cover the whole canvas. {:#alpha-blending} * **Alpha-blending**: Given that each of the R, G, B and A channels is 8-bit, and the RGB channels are _not premultiplied_ by alpha, the formula for blending 'dst' onto 'src' is: ~~~~~ blend.A = src.A + dst.A * (1 - src.A / 255) if blend.A = 0 then blend.RGB = 0 else blend.RGB = (src.RGB * src.A + dst.RGB * dst.A * (1 - src.A / 255)) / blend.A ~~~~~ * Alpha-blending SHOULD be done in linear color space, by taking into account the [color profile](#color-profile) of the image. If the color profile is not present, sRGB is to be assumed. (Note that sRGB also needs to be linearized due to a gamma of ~2.2). Frame Data: _Chunk Size_ - `16` bytes : For a fragmented frame, it consists of multiple [fragment chunks](#fragments). : For a non-fragmented frame, it consists of: * An optional [alpha subchunk](#alpha) for the frame. * A [bitstream subchunk](#bitstream-vp8vp8l) for the frame. * An optional list of [unknown chunks](#unknown-chunks). **Note**: The 'ANMF' payload, _Frame Data_ above, consists of individual _padded_ chunks as described by the [RIFF file format](#riff-file-format). #### Fragments _\[status: experimental\]_ For images that are represented by fragments, this chunk contains data for a single fragment. If the _Image Fragmentation Flag_ is not set, then this chunk SHOULD NOT be present. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('FRGM') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Fragment X | ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ... Fragment Y | Fragment Data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Fragment X: 24 bits (_uint24_) : The X coordinate of the upper left corner of the fragment is `Fragment X * 2` Fragment Y: 24 bits (_uint24_) : The Y coordinate of the upper left corner of the fragment is `Fragment Y * 2` Fragment Data: _Chunk Size_ - `6` bytes : It contains: * An optional [alpha subchunk](#alpha) for the fragment. * The [bitstream subchunk](#bitstream-vp8vp8l) for the fragment. * An optional list of [unknown chunks](#unknown-chunks). Note: The width and height of the fragment is obtained from the bitstream subchunk. The fragments of a frame SHOULD have the following properties: * They collectively cover the whole frame. * No pair of fragments have any overlapping region on the frame. * No portion of any fragment should be located outside of the canvas. #### Alpha 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('ALPH') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Rsv| P | F | C | Alpha Bitstream... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Reserved (Rsv): 2 bits : SHOULD be `0`. Pre-processing (P): 2 bits : These INFORMATIVE bits are used to signal the pre-processing that has been performed during compression. The decoder can use this information to e.g. dither the values or smooth the gradients prior to display. * `0`: no pre-processing * `1`: level reduction Filtering method (F): 2 bits : The filtering method used: * `0`: None. * `1`: Horizontal filter. * `2`: Vertical filter. * `3`: Gradient filter. For each pixel, filtering is performed using the following calculations. Assume the alpha values surrounding the current `X` position are labeled as: C | B | ---+---+ A | X | We seek to compute the alpha value at position `X`. First, a prediction is made depending on the filtering method: * Method `0`: predictor = 0 * Method `1`: predictor = A * Method `2`: predictor = B * Method `3`: predictor = clip(A + B - C) where `clip(v)` is equal to: * 0 if v < 0 * 255 if v > 255 * v otherwise The final value is derived by adding the decompressed value `X` to the predictor and using modulo-256 arithmetic to wrap the \[256-511\] range into the \[0-255\] one: `alpha = (predictor + X) % 256` There are special cases for left-most and top-most pixel positions: * Top-left value at location (0,0) uses 0 as predictor value. Otherwise, * For horizontal or gradient filtering methods, the left-most pixels at location (0, y) are predicted using the location (0, y-1) just above. * For vertical or gradient filtering methods, the top-most pixels at location (x, 0) are predicted using the location (x-1, 0) on the left. Decoders are not required to use this information in any specified way. Compression method (C): 2 bits : The compression method used: * `0`: No compression. * `1`: Compressed using the WebP lossless format. Alpha bitstream: _Chunk Size_ - `1` bytes : Encoded alpha bitstream. This optional chunk contains encoded alpha data for this frame/fragment. A frame/fragment containing a 'VP8L' chunk SHOULD NOT contain this chunk. **Rationale**: The transparency information is already part of the 'VP8L' chunk. The alpha channel data is stored as uncompressed raw data (when compression method is '0') or compressed using the lossless format (when the compression method is '1'). * Raw data: consists of a byte sequence of length width * height, containing all the 8-bit transparency values in scan order. * Lossless format compression: the byte sequence is a compressed image-stream (as described in the [WebP Lossless Bitstream Format] [webpllspec]) of implicit dimension width x height. That is, this image-stream does NOT contain any headers describing the image dimension. **Rationale**: the dimension is already known from other sources, so storing it again would be redundant and error-prone. Once the image-stream is decoded into ARGB color values, following the process described in the lossless format specification, the transparency information must be extracted from the *green* channel of the ARGB quadruplet. **Rationale**: the green channel is allowed extra transformation steps in the specification -- unlike the other channels -- that can improve compression. #### Bitstream (VP8/VP8L) This chunk contains compressed bitstream data for a single frame/fragment. A bitstream chunk may be either (i) a VP8 chunk, using "VP8 " (note the significant fourth-character space) as its tag _or_ (ii) a VP8L chunk, using "VP8L" as its tag. The formats of VP8 and VP8L chunks are as described in sections [Simple file format (lossy)](#simple-file-format-lossy) and [Simple file format (lossless)](#simple-file-format-lossless) respectively. #### Color profile 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('ICCP') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Color Profile | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Color Profile: _Chunk Size_ bytes : ICC profile. This chunk MUST appear before the image data. There SHOULD be at most one such chunk. If there are more such chunks, readers MAY ignore all except the first one. See the [ICC Specification][iccspec] for details. If this chunk is not present, sRGB SHOULD be assumed. #### Metadata Metadata can be stored in 'EXIF' or 'XMP ' chunks. There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there are more such chunks, readers MAY ignore all except the first one. Also, a file may possibly contain both 'EXIF' and 'XMP ' chunks. The chunks are defined as follows: EXIF chunk: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('EXIF') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | EXIF Metadata | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ EXIF Metadata: _Chunk Size_ bytes : image metadata in EXIF format. XMP chunk: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ChunkHeader('XMP ') | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | XMP Metadata | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ XMP Metadata: _Chunk Size_ bytes : image metadata in XMP format. Additional guidance about handling metadata can be found in the Metadata Working Group's [Guidelines for Handling Metadata][metadata]. #### Unknown Chunks _\[status: experimental\]_ A RIFF chunk (described in [this](#terminology-amp-basics) section) whose _chunk tag_ is different from any of the chunks described in this document, is considered an _unknown chunk_. **Rationale**: Allowing unknown chunks gives a provision for future extension of the format, and also allows storage of any application-specific data. A file MAY contain unknown chunks: * At the end of the file as described in [Extended WebP file header](#extended_header) section. * At the end of FRGM and ANMF chunks as described in [Fragments](#fragments) and [Animation](#animation) sections. Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their original order (unless they specifically intend to modify these chunks). ### Assembling the Canvas from fragments/frames Here we provide an overview of how a reader should assemble a canvas in case of a fragmented-image and in case of an animated image. The notation _VP8X.field_ means the field in the 'VP8X' chunk with the same description. Displaying a _fragmented image_ canvas MUST be equivalent to the following pseudocode: _\[status: experimental\]_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ assert VP8X.flags.hasFragments canvas ↠new black image of size VP8X.canvasWidth x VP8X.canvasHeight. frgm_params ↠nil for chunk in image_data: assert chunk.tag is "FRGM" frgm_params.fragmentX = Fragment X frgm_params.fragmentY = Fragment Y for subchunk in 'Fragment Data': if subchunk.tag == "ALPH": assert alpha subchunks not found in 'Fragment Data' earlier frgm_params.alpha = alpha_data else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L": assert bitstream subchunks not found in 'Fragment Data' earlier frgm_params.bitstream = bitstream_data frgm_params.fragmentWidth = Width extracted from bitstream subchunk frgm_params.fragmentHeight = Height extracted from bitstream subchunk assert VP8X.canvasWidth >= frgm_params.fragmentX + frgm_params.fragmentWidth assert VP8X.canvasHeight >= frgm_params.fragmentY + frgm_params.fragmentHeight assert fragment has the properties mentioned in "Image Fragments" section. render fragment with frame_params.alpha and frame_params.bitstream on canvas with top-left corner in (frgm_params.fragmentX, frgm_params.fragmentY). canvas contains the decoded canvas. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Displaying an _animated image_ canvas MUST be equivalent to the following pseudocode: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ assert VP8X.flags.hasAnimation canvas ↠new image of size VP8X.canvasWidth x VP8X.canvasHeight with background color ANIM.background_color. loop_count ↠ANIM.loopCount dispose_method ↠ANIM.disposeMethod if loop_count == 0: loop_count = ∞ frame_params ↠nil for loop = 0, ..., loop_count - 1 assert next chunk in image_data is ANMF frame_params.frameX = Frame X frame_params.frameY = Frame Y frame_params.frameWidth = Frame Width Minus One + 1 frame_params.frameHeight = Frame Height Minus One + 1 frame_params.frameDuration = Frame Duration assert VP8X.canvasWidth >= frame_params.frameX + frame_params.frameWidth assert VP8X.canvasHeight >= frame_params.frameY + frame_params.frameHeight if VP8X.flags.hasFragments and first subchunk in 'Frame Data' is FRGM // Fragmented frame. frame_params.{bitstream,alpha} = canvas decoded from subchunks in 'Frame Data' as per the pseudocode for _fragmented image_ above. else // Non-fragmented frame. for subchunk in 'Frame Data': if subchunk.tag == "ALPH": assert alpha subchunks not found in 'Frame Data' earlier frame_params.alpha = alpha_data else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L": assert bitstream subchunks not found in 'Frame Data' earlier frame_params.bitstream = bitstream_data render frame with frame_params.alpha and frame_params.bitstream on canvas with top-left corner in (frame_params.frameX, frame_params.frameY), using dispose method dispose_method. Show the contents of the image for frame_params.frameDuration * 1ms. canvas contains the decoded canvas. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Example file layouts -------------------- A lossy encoded image with alpha may look as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RIFF/WEBP +- VP8X (descriptions of features used) +- ALPH (alpha bitstream) +- VP8 (bitstream) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A losslessly encoded image may look as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RIFF/WEBP +- VP8X (descriptions of features used) +- XYZW (unknown chunk) +- VP8L (lossless bitstream) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A lossless image with ICC profile and XMP metadata may look as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RIFF/WEBP +- VP8X (descriptions of features used) +- ICCP (color profile) +- VP8L (lossless bitstream) +- XMP (metadata) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A fragmented image may look as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RIFF/WEBP +- VP8X (descriptions of features used) +- FRGM (fragment1 parameters + data) +- FRGM (fragment2 parameters + data) +- FRGM (fragment3 parameters + data) +- FRGM (fragment4 parameters + data) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ An animated image with EXIF metadata may look as follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RIFF/WEBP +- VP8X (descriptions of features used) +- ANIM (global animation parameters) +- ANMF (frame1 parameters + data) +- ANMF (frame2 parameters + data) +- ANMF (frame3 parameters + data) +- ANMF (frame4 parameters + data) +- EXIF (metadata) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [vp8spec]: http://tools.ietf.org/html/rfc6386 [webpllspec]: https://gerrit.chromium.org/gerrit/gitweb?p=webm/libwebp.git;a=blob;f=doc/webp-lossless-bitstream-spec.txt;hb=master [iccspec]: http://www.color.org/icc_specs2.xalter [metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf [rfc 2119]: http://tools.ietf.org/html/rfc2119 libwebp-0.4.0/doc/template.html0000644000014400001440000000361112255002107013310 0ustar WebP Container Specification <%= @body %> libwebp-0.4.0/config.sub0000755000014400001440000010517612255206714012050 0ustar #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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 2 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 . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libwebp-0.4.0/Android.mk0000644000014400001440000000457512255002107011765 0ustar LOCAL_PATH := $(call my-dir) WEBP_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD -DWEBP_USE_THREAD ifeq ($(APP_OPTIM),release) WEBP_CFLAGS += -finline-functions -frename-registers -ffast-math -s \ -ffunction-sections -fdata-sections endif include $(CLEAR_VARS) LOCAL_SRC_FILES := \ src/dec/alpha.c \ src/dec/buffer.c \ src/dec/frame.c \ src/dec/idec.c \ src/dec/io.c \ src/dec/layer.c \ src/dec/quant.c \ src/dec/tree.c \ src/dec/vp8.c \ src/dec/vp8l.c \ src/dec/webp.c \ src/dsp/cpu.c \ src/dsp/dec.c \ src/dsp/dec_sse2.c \ src/dsp/enc.c \ src/dsp/enc_sse2.c \ src/dsp/lossless.c \ src/dsp/upsampling.c \ src/dsp/upsampling_sse2.c \ src/dsp/yuv.c \ src/enc/alpha.c \ src/enc/analysis.c \ src/enc/backward_references.c \ src/enc/config.c \ src/enc/cost.c \ src/enc/filter.c \ src/enc/frame.c \ src/enc/histogram.c \ src/enc/iterator.c \ src/enc/layer.c \ src/enc/picture.c \ src/enc/quant.c \ src/enc/syntax.c \ src/enc/token.c \ src/enc/tree.c \ src/enc/vp8l.c \ src/enc/webpenc.c \ src/utils/alpha_processing.c \ src/utils/bit_reader.c \ src/utils/bit_writer.c \ src/utils/color_cache.c \ src/utils/filters.c \ src/utils/huffman.c \ src/utils/huffman_encode.c \ src/utils/quant_levels.c \ src/utils/quant_levels_dec.c \ src/utils/random.c \ src/utils/rescaler.c \ src/utils/thread.c \ src/utils/utils.c \ LOCAL_CFLAGS := $(WEBP_CFLAGS) LOCAL_C_INCLUDES += $(LOCAL_PATH)/src # prefer arm over thumb mode for performance gains LOCAL_ARM_MODE := arm ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) # Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal # instructions to be generated for armv7a code. Instead target the neon code # specifically. LOCAL_SRC_FILES += src/dsp/dec_neon.c.neon LOCAL_SRC_FILES += src/dsp/upsampling_neon.c.neon LOCAL_SRC_FILES += src/dsp/enc_neon.c.neon endif LOCAL_STATIC_LIBRARIES := cpufeatures LOCAL_MODULE := webp include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ examples/dwebp.c \ examples/example_util.c \ LOCAL_CFLAGS := $(WEBP_CFLAGS) LOCAL_C_INCLUDES := $(LOCAL_PATH)/src LOCAL_STATIC_LIBRARIES := webp LOCAL_MODULE := dwebp include $(BUILD_EXECUTABLE) $(call import-module,android/cpufeatures) libwebp-0.4.0/NEWS0000644000014400001440000000626512255002107010551 0ustar - 12/19/13: version 0.4.0 * improved gif2webp tool * numerous fixes, compression improvement and speed-up * dither option added to decoder (dwebp -dither 50 ...) * improved multi-threaded modes (-mt option) * improved filtering strength determination * New function: WebPMuxGetCanvasSize * BMP and TIFF format output added to 'dwebp' * Significant memory reduction for decoding lossy images with alpha. * Intertwined decoding of RGB and alpha for a shorter time-to-first-decoded-pixel. * WebPIterator has a new member 'has_alpha' denoting whether the frame contains transparency. * Container spec amended with new 'blending method' for animation. - 6/13/13: version 0.3.1 This is a binary compatible release. * Add incremental decoding support for images containing ALPH and ICCP chunks. * Python bindings via swig for the simple encode/decode interfaces similar to Java. - 3/20/13: version 0.3.0 This is a binary compatible release. * WebPINewRGB/WebPINewYUVA accept being passed a NULL output buffer and will perform auto-allocation. * default filter option is now '-strong -f 60' * encoding speed-up for lossy methods 3 to 6 * alpha encoding can be done in parallel to lossy using 'cwebp -mt ...' * color profile, metadata (XMP/EXIF) and animation support finalized in the container. * various NEON assembly additions Tool updates / additions: * gif2webp added * vwebp given color profile & animation support * cwebp can preserve color profile / metadata with '-metadata' - 10/30/12: version 0.2.1 * Various security related fixes * cwebp.exe: fix import errors on Windows XP * enable DLL builds for mingw targets - 8/3/12: version 0.2.0 * Add support for ARGB -> YUVA conversion for lossless decoder New functions: WebPINewYUVA, WebPIDecGetYUVA * Add stats for lossless and alpha encoding * Security related hardening: allocation and size checks * Add PAM output support to dwebp - 7/19/12: version 0.1.99 * This is a pre-release of 0.2.0, not an rc to allow for further incompatible changes based on user feedback. * Alpha channel encode/decode support. * Lossless encoder/decoder. * Add TIFF input support to cwebp. Incompatible changes: * The encode ABI has been modified to support alpha encoding. * Deprecated function WebPINew() has been removed. * Decode function signatures have changed to consistently use size_t over int/uint32_t. * decode_vp8.h is no longer installed system-wide. * cwebp will encode the alpha channel if present. - 9/19/11: version 0.1.3 * Advanced decoding APIs. * On-the-fly cropping and rescaling of images. * SSE2 instructions for decoding performance optimizations on x86 based platforms. * Support Multi-threaded decoding. * 40% improvement in Decoding performance. * Add support for RGB565, RGBA4444 & ARGB image colorspace. * Better handling of large picture encoding. - 3/25/11: version 0.1.2 * Incremental decoding: picture can be decoded byte-by-byte if needs be. * lot of bug-fixes, consolidation and stabilization - 2/23/11: initial release of version 0.1, with the new encoder - 9/30/10: initial release version with only the lightweight decoder libwebp-0.4.0/examples/0000755000014400001440000000000012255206714011671 5ustar libwebp-0.4.0/examples/gif2webp_util.c0000644000014400001440000005620512255002107014575 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Helper structs and methods for gif2webp tool. // #include #include #include "webp/encode.h" #include "./gif2webp_util.h" #define DELTA_INFINITY 1ULL << 32 #define KEYFRAME_NONE -1 //------------------------------------------------------------------------------ // Helper utilities. static void ClearRectangle(WebPPicture* const picture, int left, int top, int width, int height) { int j; for (j = top; j < top + height; ++j) { uint32_t* const dst = picture->argb + j * picture->argb_stride; int i; for (i = left; i < left + width; ++i) { dst[i] = WEBP_UTIL_TRANSPARENT_COLOR; } } } void WebPUtilClearPic(WebPPicture* const picture, const WebPFrameRect* const rect) { if (rect != NULL) { ClearRectangle(picture, rect->x_offset, rect->y_offset, rect->width, rect->height); } else { ClearRectangle(picture, 0, 0, picture->width, picture->height); } } // TODO: Also used in picture.c. Move to a common location? // Copy width x height pixels from 'src' to 'dst' honoring the strides. static void CopyPlane(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width, int height) { while (height-- > 0) { memcpy(dst, src, width); src += src_stride; dst += dst_stride; } } // Copy pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are assumed // to be already allocated. static void CopyPixels(const WebPPicture* const src, WebPPicture* const dst) { assert(src->width == dst->width && src->height == dst->height); CopyPlane((uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb, 4 * dst->argb_stride, 4 * src->width, src->height); } // Given 'src' picture and its frame rectangle 'rect', blend it into 'dst'. static void BlendPixels(const WebPPicture* const src, const WebPFrameRect* const rect, WebPPicture* const dst) { int j; assert(src->width == dst->width && src->height == dst->height); for (j = rect->y_offset; j < rect->y_offset + rect->height; ++j) { int i; for (i = rect->x_offset; i < rect->x_offset + rect->width; ++i) { const uint32_t src_pixel = src->argb[j * src->argb_stride + i]; const int src_alpha = src_pixel >> 24; if (src_alpha != 0) { dst->argb[j * dst->argb_stride + i] = src_pixel; } } } } // Replace transparent pixels within 'dst_rect' of 'dst' by those in the 'src'. static void ReduceTransparency(const WebPPicture* const src, const WebPFrameRect* const rect, WebPPicture* const dst) { int i, j; assert(src != NULL && dst != NULL && rect != NULL); assert(src->width == dst->width && src->height == dst->height); for (j = rect->y_offset; j < rect->y_offset + rect->height; ++j) { for (i = rect->x_offset; i < rect->x_offset + rect->width; ++i) { const uint32_t src_pixel = src->argb[j * src->argb_stride + i]; const int src_alpha = src_pixel >> 24; const uint32_t dst_pixel = dst->argb[j * dst->argb_stride + i]; const int dst_alpha = dst_pixel >> 24; if (dst_alpha == 0 && src_alpha == 0xff) { dst->argb[j * dst->argb_stride + i] = src_pixel; } } } } // Replace similar blocks of pixels by a 'see-through' transparent block // with uniform average color. static void FlattenSimilarBlocks(const WebPPicture* const src, const WebPFrameRect* const rect, WebPPicture* const dst) { int i, j; const int block_size = 8; const int y_start = (rect->y_offset + block_size) & ~(block_size - 1); const int y_end = (rect->y_offset + rect->height) & ~(block_size - 1); const int x_start = (rect->x_offset + block_size) & ~(block_size - 1); const int x_end = (rect->x_offset + rect->width) & ~(block_size - 1); assert(src != NULL && dst != NULL && rect != NULL); assert(src->width == dst->width && src->height == dst->height); assert((block_size & (block_size - 1)) == 0); // must be a power of 2 // Iterate over each block and count similar pixels. for (j = y_start; j < y_end; j += block_size) { for (i = x_start; i < x_end; i += block_size) { int cnt = 0; int avg_r = 0, avg_g = 0, avg_b = 0; int x, y; const uint32_t* const psrc = src->argb + j * src->argb_stride + i; uint32_t* const pdst = dst->argb + j * dst->argb_stride + i; for (y = 0; y < block_size; ++y) { for (x = 0; x < block_size; ++x) { const uint32_t src_pixel = psrc[x + y * src->argb_stride]; const int alpha = src_pixel >> 24; if (alpha == 0xff && src_pixel == pdst[x + y * dst->argb_stride]) { ++cnt; avg_r += (src_pixel >> 16) & 0xff; avg_g += (src_pixel >> 8) & 0xff; avg_b += (src_pixel >> 0) & 0xff; } } } // If we have a fully similar block, we replace it with an // average transparent block. This compresses better in lossy mode. if (cnt == block_size * block_size) { const uint32_t color = (0x00 << 24) | ((avg_r / cnt) << 16) | ((avg_g / cnt) << 8) | ((avg_b / cnt) << 0); for (y = 0; y < block_size; ++y) { for (x = 0; x < block_size; ++x) { pdst[x + y * dst->argb_stride] = color; } } } } } } //------------------------------------------------------------------------------ // Key frame related utilities. // Returns true if 'curr' frame with frame rectangle 'curr_rect' is a key frame, // that is, it can be decoded independently of 'prev' canvas. static int IsKeyFrame(const WebPPicture* const curr, const WebPFrameRect* const curr_rect, const WebPPicture* const prev) { int i, j; int is_key_frame = 1; // If previous canvas (with previous frame disposed) is all transparent, // current frame is a key frame. for (i = 0; i < prev->width; ++i) { for (j = 0; j < prev->height; ++j) { const uint32_t prev_alpha = (prev->argb[j * prev->argb_stride + i]) >> 24; if (prev_alpha != 0) { is_key_frame = 0; break; } } if (!is_key_frame) break; } if (is_key_frame) return 1; // If current frame covers the whole canvas and does not contain any // transparent pixels that depend on previous canvas, then current frame is // a key frame. if (curr_rect->width == curr->width && curr_rect->height == curr->height) { assert(curr_rect->x_offset == 0 && curr_rect->y_offset == 0); is_key_frame = 1; for (j = 0; j < prev->height; ++j) { for (i = 0; i < prev->width; ++i) { const uint32_t prev_alpha = (prev->argb[j * prev->argb_stride + i]) >> 24; const uint32_t curr_alpha = (curr->argb[j * curr->argb_stride + i]) >> 24; if (curr_alpha != 0xff && prev_alpha != 0) { is_key_frame = 0; break; } } if (!is_key_frame) break; } if (is_key_frame) return 1; } return 0; } // Given 'prev' frame and current frame rectangle 'rect', convert 'curr' frame // to a key frame. static void ConvertToKeyFrame(const WebPPicture* const prev, WebPFrameRect* const rect, WebPPicture* const curr) { int j; assert(curr->width == prev->width && curr->height == prev->height); // Replace transparent pixels of current canvas with those from previous // canvas (with previous frame disposed). for (j = 0; j < curr->height; ++j) { int i; for (i = 0; i < curr->width; ++i) { uint32_t* const curr_pixel = curr->argb + j * curr->argb_stride + i; const int curr_alpha = *curr_pixel >> 24; if (curr_alpha == 0) { *curr_pixel = prev->argb[j * prev->argb_stride + i]; } } } // Frame rectangle now covers the whole canvas. rect->x_offset = 0; rect->y_offset = 0; rect->width = curr->width; rect->height = curr->height; } //------------------------------------------------------------------------------ // Encoded frame. // Used to store two candidates of encoded data for an animation frame. One of // the two will be chosen later. typedef struct { WebPMuxFrameInfo sub_frame; // Encoded frame rectangle. WebPMuxFrameInfo key_frame; // Encoded frame if it was converted to keyframe. } EncodedFrame; // Release the data contained by 'encoded_frame'. static void FrameRelease(EncodedFrame* const encoded_frame) { if (encoded_frame != NULL) { WebPDataClear(&encoded_frame->sub_frame.bitstream); WebPDataClear(&encoded_frame->key_frame.bitstream); memset(encoded_frame, 0, sizeof(*encoded_frame)); } } //------------------------------------------------------------------------------ // Frame cache. // Used to store encoded frames that haven't been output yet. struct WebPFrameCache { EncodedFrame* encoded_frames; // Array of encoded frames. size_t size; // Number of allocated data elements. size_t start; // Start index. size_t count; // Number of valid data elements. int flush_count; // If >0, ‘flush_count’ frames starting from // 'start' are ready to be added to mux. int64_t best_delta; // min(canvas size - frame size) over the frames. // Can be negative in certain cases due to // transparent pixels in a frame. int keyframe; // Index of selected keyframe relative to 'start'. size_t kmin; // Min distance between key frames. size_t kmax; // Max distance between key frames. size_t count_since_key_frame; // Frames seen since the last key frame. int allow_mixed; // If true, each frame can be lossy or lossless. WebPPicture prev_canvas; // Previous canvas (properly disposed). WebPPicture curr_canvas; // Current canvas (temporary buffer). int is_first_frame; // True if no frames have been added to the cache // since WebPFrameCacheNew(). }; // Reset the counters in the cache struct. Doesn't touch 'cache->encoded_frames' // and 'cache->size'. static void CacheReset(WebPFrameCache* const cache) { cache->start = 0; cache->count = 0; cache->flush_count = 0; cache->best_delta = DELTA_INFINITY; cache->keyframe = KEYFRAME_NONE; } WebPFrameCache* WebPFrameCacheNew(int width, int height, size_t kmin, size_t kmax, int allow_mixed) { WebPFrameCache* cache = (WebPFrameCache*)malloc(sizeof(*cache)); if (cache == NULL) return NULL; CacheReset(cache); // sanity init, so we can call WebPFrameCacheDelete(): cache->encoded_frames = NULL; cache->is_first_frame = 1; // Picture buffers. if (!WebPPictureInit(&cache->prev_canvas) || !WebPPictureInit(&cache->curr_canvas)) { return NULL; } cache->prev_canvas.width = width; cache->prev_canvas.height = height; cache->prev_canvas.use_argb = 1; if (!WebPPictureAlloc(&cache->prev_canvas) || !WebPPictureCopy(&cache->prev_canvas, &cache->curr_canvas)) { goto Err; } WebPUtilClearPic(&cache->prev_canvas, NULL); // Cache data. cache->allow_mixed = allow_mixed; cache->kmin = kmin; cache->kmax = kmax; cache->count_since_key_frame = 0; assert(kmax > kmin); cache->size = kmax - kmin; cache->encoded_frames = (EncodedFrame*)calloc(cache->size, sizeof(*cache->encoded_frames)); if (cache->encoded_frames == NULL) goto Err; return cache; // All OK. Err: WebPFrameCacheDelete(cache); return NULL; } void WebPFrameCacheDelete(WebPFrameCache* const cache) { if (cache != NULL) { if (cache->encoded_frames != NULL) { size_t i; for (i = 0; i < cache->size; ++i) { FrameRelease(&cache->encoded_frames[i]); } free(cache->encoded_frames); } WebPPictureFree(&cache->prev_canvas); WebPPictureFree(&cache->curr_canvas); free(cache); } } static int EncodeFrame(const WebPConfig* const config, WebPPicture* const pic, WebPMemoryWriter* const memory) { pic->use_argb = 1; pic->writer = WebPMemoryWrite; pic->custom_ptr = memory; if (!WebPEncode(config, pic)) { return 0; } return 1; } static void GetEncodedData(const WebPMemoryWriter* const memory, WebPData* const encoded_data) { encoded_data->bytes = memory->mem; encoded_data->size = memory->size; } #define MIN_COLORS_LOSSY 31 // Don't try lossy below this threshold. #define MAX_COLORS_LOSSLESS 194 // Don't try lossless above this threshold. #define MAX_COLOR_COUNT 256 // Power of 2 greater than MAX_COLORS_LOSSLESS. #define HASH_SIZE (MAX_COLOR_COUNT * 4) #define HASH_RIGHT_SHIFT 22 // 32 - log2(HASH_SIZE). // TODO(urvang): Also used in enc/vp8l.c. Move to utils. // If the number of colors in the 'pic' is at least MAX_COLOR_COUNT, return // MAX_COLOR_COUNT. Otherwise, return the exact number of colors in the 'pic'. static int GetColorCount(const WebPPicture* const pic) { int x, y; int num_colors = 0; uint8_t in_use[HASH_SIZE] = { 0 }; uint32_t colors[HASH_SIZE]; static const uint32_t kHashMul = 0x1e35a7bd; const uint32_t* argb = pic->argb; const int width = pic->width; const int height = pic->height; uint32_t last_pix = ~argb[0]; // so we're sure that last_pix != argb[0] for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { int key; if (argb[x] == last_pix) { continue; } last_pix = argb[x]; key = (kHashMul * last_pix) >> HASH_RIGHT_SHIFT; while (1) { if (!in_use[key]) { colors[key] = last_pix; in_use[key] = 1; ++num_colors; if (num_colors >= MAX_COLOR_COUNT) { return MAX_COLOR_COUNT; // Exact count not needed. } break; } else if (colors[key] == last_pix) { break; // The color is already there. } else { // Some other color sits here, so do linear conflict resolution. ++key; key &= (HASH_SIZE - 1); // Key mask. } } } argb += pic->argb_stride; } return num_colors; } #undef MAX_COLOR_COUNT #undef HASH_SIZE #undef HASH_RIGHT_SHIFT static int SetFrame(const WebPConfig* const config, int allow_mixed, int is_key_frame, const WebPPicture* const prev_canvas, WebPPicture* const frame, const WebPFrameRect* const rect, const WebPMuxFrameInfo* const info, WebPPicture* const sub_frame, EncodedFrame* encoded_frame) { int try_lossless; int try_lossy; int try_both; WebPMemoryWriter mem1, mem2; WebPData* encoded_data; WebPMuxFrameInfo* const dst = is_key_frame ? &encoded_frame->key_frame : &encoded_frame->sub_frame; *dst = *info; encoded_data = &dst->bitstream; WebPMemoryWriterInit(&mem1); WebPMemoryWriterInit(&mem2); if (!allow_mixed) { try_lossless = config->lossless; try_lossy = !try_lossless; } else { // Use a heuristic for trying lossless and/or lossy compression. const int num_colors = GetColorCount(sub_frame); try_lossless = (num_colors < MAX_COLORS_LOSSLESS); try_lossy = (num_colors >= MIN_COLORS_LOSSY); } try_both = try_lossless && try_lossy; if (try_lossless) { WebPConfig config_ll = *config; config_ll.lossless = 1; if (!EncodeFrame(&config_ll, sub_frame, &mem1)) { goto Err; } } if (try_lossy) { WebPConfig config_lossy = *config; config_lossy.lossless = 0; if (!is_key_frame) { // For lossy compression of a frame, it's better to replace transparent // pixels of 'curr' with actual RGB values, whenever possible. ReduceTransparency(prev_canvas, rect, frame); // TODO(later): Investigate if this helps lossless compression as well. FlattenSimilarBlocks(prev_canvas, rect, frame); } if (!EncodeFrame(&config_lossy, sub_frame, &mem2)) { goto Err; } } if (try_both) { // Pick the encoding with smallest size. // TODO(later): Perhaps a rough SSIM/PSNR produced by the encoder should // also be a criteria, in addition to sizes. if (mem1.size <= mem2.size) { free(mem2.mem); GetEncodedData(&mem1, encoded_data); } else { free(mem1.mem); GetEncodedData(&mem2, encoded_data); } } else { GetEncodedData(try_lossless ? &mem1 : &mem2, encoded_data); } return 1; Err: free(mem1.mem); free(mem2.mem); return 0; } #undef MIN_COLORS_LOSSY #undef MAX_COLORS_LOSSLESS // Returns cached frame at given 'position' index. static EncodedFrame* CacheGetFrame(const WebPFrameCache* const cache, size_t position) { assert(cache->start + position < cache->size); return &cache->encoded_frames[cache->start + position]; } // Calculate the penalty incurred if we encode given frame as a key frame // instead of a sub-frame. static int64_t KeyFramePenalty(const EncodedFrame* const encoded_frame) { return ((int64_t)encoded_frame->key_frame.bitstream.size - encoded_frame->sub_frame.bitstream.size); } static void DisposeFrame(WebPMuxAnimDispose dispose_method, const WebPFrameRect* const gif_rect, WebPPicture* const frame, WebPPicture* const canvas) { if (dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { WebPUtilClearPic(frame, NULL); WebPUtilClearPic(canvas, gif_rect); } } int WebPFrameCacheAddFrame(WebPFrameCache* const cache, const WebPConfig* const config, const WebPFrameRect* const orig_rect, WebPPicture* const frame, WebPMuxFrameInfo* const info) { int ok = 0; WebPFrameRect rect = *orig_rect; WebPPicture sub_image; // View extracted from 'frame' with rectangle 'rect'. WebPPicture* const prev_canvas = &cache->prev_canvas; const size_t position = cache->count; const int allow_mixed = cache->allow_mixed; EncodedFrame* const encoded_frame = CacheGetFrame(cache, position); assert(position < cache->size); // Snap to even offsets (and adjust dimensions if needed). rect.width += (rect.x_offset & 1); rect.height += (rect.y_offset & 1); rect.x_offset &= ~1; rect.y_offset &= ~1; if (!WebPPictureView(frame, rect.x_offset, rect.y_offset, rect.width, rect.height, &sub_image)) { return 0; } info->x_offset = rect.x_offset; info->y_offset = rect.y_offset; ++cache->count; if (cache->is_first_frame || IsKeyFrame(frame, &rect, prev_canvas)) { // Add this as a key frame. if (!SetFrame(config, allow_mixed, 1, NULL, NULL, NULL, info, &sub_image, encoded_frame)) { goto End; } cache->keyframe = position; cache->flush_count = cache->count; cache->count_since_key_frame = 0; // Update prev_canvas by simply copying from 'curr'. CopyPixels(frame, prev_canvas); } else { ++cache->count_since_key_frame; if (cache->count_since_key_frame <= cache->kmin) { // Add this as a frame rectangle. if (!SetFrame(config, allow_mixed, 0, prev_canvas, frame, &rect, info, &sub_image, encoded_frame)) { goto End; } cache->flush_count = cache->count; // Update prev_canvas by blending 'curr' into it. BlendPixels(frame, orig_rect, prev_canvas); } else { WebPPicture full_image; WebPMuxFrameInfo full_image_info; int frame_added; int64_t curr_delta; // Add frame rectangle to cache. if (!SetFrame(config, allow_mixed, 0, prev_canvas, frame, &rect, info, &sub_image, encoded_frame)) { goto End; } // Convert to a key frame. CopyPixels(frame, &cache->curr_canvas); ConvertToKeyFrame(prev_canvas, &rect, &cache->curr_canvas); if (!WebPPictureView(&cache->curr_canvas, rect.x_offset, rect.y_offset, rect.width, rect.height, &full_image)) { goto End; } full_image_info = *info; full_image_info.x_offset = rect.x_offset; full_image_info.y_offset = rect.y_offset; // Add key frame to cache, too. frame_added = SetFrame(config, allow_mixed, 1, NULL, NULL, NULL, &full_image_info, &full_image, encoded_frame); WebPPictureFree(&full_image); if (!frame_added) goto End; // Analyze size difference of the two variants. curr_delta = KeyFramePenalty(encoded_frame); if (curr_delta <= cache->best_delta) { // Pick this as keyframe. cache->keyframe = position; cache->best_delta = curr_delta; cache->flush_count = cache->count - 1; // We can flush previous frames. } if (cache->count_since_key_frame == cache->kmax) { cache->flush_count = cache->count; cache->count_since_key_frame = 0; } // Update prev_canvas by simply copying from 'curr_canvas'. CopyPixels(&cache->curr_canvas, prev_canvas); } } DisposeFrame(info->dispose_method, orig_rect, frame, prev_canvas); cache->is_first_frame = 0; ok = 1; End: WebPPictureFree(&sub_image); if (!ok) { FrameRelease(encoded_frame); --cache->count; // We reset the count, as the frame addition failed. } return ok; } WebPMuxError WebPFrameCacheFlush(WebPFrameCache* const cache, int verbose, WebPMux* const mux) { while (cache->flush_count > 0) { WebPMuxFrameInfo* info; WebPMuxError err; EncodedFrame* const curr = CacheGetFrame(cache, 0); // Pick frame or full canvas. if (cache->keyframe == 0) { info = &curr->key_frame; info->blend_method = WEBP_MUX_NO_BLEND; cache->keyframe = KEYFRAME_NONE; cache->best_delta = DELTA_INFINITY; } else { info = &curr->sub_frame; info->blend_method = WEBP_MUX_BLEND; } // Add to mux. err = WebPMuxPushFrame(mux, info, 1); if (err != WEBP_MUX_OK) return err; if (verbose) { printf("Added frame. offset:%d,%d duration:%d dispose:%d blend:%d\n", info->x_offset, info->y_offset, info->duration, info->dispose_method, info->blend_method); } FrameRelease(curr); ++cache->start; --cache->flush_count; --cache->count; if (cache->keyframe != KEYFRAME_NONE) --cache->keyframe; } if (cache->count == 0) CacheReset(cache); return WEBP_MUX_OK; } WebPMuxError WebPFrameCacheFlushAll(WebPFrameCache* const cache, int verbose, WebPMux* const mux) { cache->flush_count = cache->count; // Force flushing of all frames. return WebPFrameCacheFlush(cache, verbose, mux); } //------------------------------------------------------------------------------ libwebp-0.4.0/examples/wicdec.c0000644000014400001440000003172512255002107013271 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Windows Imaging Component (WIC) decode. #include "./wicdec.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_WINCODEC_H #ifdef __MINGW32__ #define INITGUID // Without this GUIDs are declared extern and fail to link #endif #define CINTERFACE #define COBJMACROS #define _WIN32_IE 0x500 // Workaround bug in shlwapi.h when compiling C++ // code with COBJMACROS. #include #include #include #include "webp/encode.h" #include "./metadata.h" #define IFS(fn) \ do { \ if (SUCCEEDED(hr)) { \ hr = (fn); \ if (FAILED(hr)) fprintf(stderr, #fn " failed %08lx\n", hr); \ } \ } while (0) // modified version of DEFINE_GUID from guiddef.h. #define WEBP_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ static const GUID name = \ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } #ifdef __cplusplus #define MAKE_REFGUID(x) (x) #else #define MAKE_REFGUID(x) &(x) #endif typedef struct WICFormatImporter { const GUID* pixel_format; int bytes_per_pixel; int (*import)(WebPPicture* const, const uint8_t* const, int); } WICFormatImporter; // From Microsoft SDK 7.0a -- wincodec.h // Create local copies for compatibility when building against earlier // versions of the SDK. WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppBGR_, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c); WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppRGB_, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d); WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppBGRA_, 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f); WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppRGBA_, 0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9); static HRESULT OpenInputStream(const char* filename, IStream** stream) { HRESULT hr = S_OK; IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream)); if (FAILED(hr)) { fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr); } return hr; } // ----------------------------------------------------------------------------- // Metadata processing // Stores the first non-zero sized color profile from 'frame' to 'iccp'. // Returns an HRESULT to indicate success or failure. The caller is responsible // for freeing 'iccp->bytes' in either case. static HRESULT ExtractICCP(IWICImagingFactory* const factory, IWICBitmapFrameDecode* const frame, MetadataPayload* const iccp) { HRESULT hr = S_OK; UINT i, count; IWICColorContext** color_contexts; IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count)); if (FAILED(hr) || count == 0) return hr; color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts)); if (color_contexts == NULL) return E_OUTOFMEMORY; for (i = 0; SUCCEEDED(hr) && i < count; ++i) { IFS(IWICImagingFactory_CreateColorContext(factory, &color_contexts[i])); } if (SUCCEEDED(hr)) { UINT num_color_contexts; IFS(IWICBitmapFrameDecode_GetColorContexts(frame, count, color_contexts, &num_color_contexts)); for (i = 0; SUCCEEDED(hr) && i < num_color_contexts; ++i) { WICColorContextType type; IFS(IWICColorContext_GetType(color_contexts[i], &type)); if (SUCCEEDED(hr) && type == WICColorContextProfile) { UINT size; IFS(IWICColorContext_GetProfileBytes(color_contexts[i], 0, NULL, &size)); if (size > 0) { iccp->bytes = (uint8_t*)malloc(size); if (iccp->bytes == NULL) { hr = E_OUTOFMEMORY; break; } iccp->size = size; IFS(IWICColorContext_GetProfileBytes(color_contexts[i], (UINT)iccp->size, iccp->bytes, &size)); if (SUCCEEDED(hr) && size != iccp->size) { fprintf(stderr, "Warning! ICC profile size (%u) != expected (%u)\n", size, (uint32_t)iccp->size); iccp->size = size; } break; } } } } for (i = 0; i < count; ++i) { if (color_contexts[i] != NULL) IUnknown_Release(color_contexts[i]); } free(color_contexts); return hr; } static HRESULT ExtractMetadata(IWICImagingFactory* const factory, IWICBitmapFrameDecode* const frame, Metadata* const metadata) { // TODO(jzern): add XMP/EXIF extraction. const HRESULT hr = ExtractICCP(factory, frame, &metadata->iccp); if (FAILED(hr)) MetadataFree(metadata); return hr; } // ----------------------------------------------------------------------------- static int HasPalette(GUID pixel_format) { return (IsEqualGUID(MAKE_REFGUID(pixel_format), MAKE_REFGUID(GUID_WICPixelFormat1bppIndexed)) || IsEqualGUID(MAKE_REFGUID(pixel_format), MAKE_REFGUID(GUID_WICPixelFormat2bppIndexed)) || IsEqualGUID(MAKE_REFGUID(pixel_format), MAKE_REFGUID(GUID_WICPixelFormat4bppIndexed)) || IsEqualGUID(MAKE_REFGUID(pixel_format), MAKE_REFGUID(GUID_WICPixelFormat8bppIndexed))); } static int HasAlpha(IWICImagingFactory* const factory, IWICBitmapDecoder* const decoder, IWICBitmapFrameDecode* const frame, GUID pixel_format) { int has_alpha; if (HasPalette(pixel_format)) { IWICPalette* frame_palette = NULL; IWICPalette* global_palette = NULL; BOOL frame_palette_has_alpha = FALSE; BOOL global_palette_has_alpha = FALSE; // A palette may exist at the frame or container level, // check IWICPalette::HasAlpha() for both if present. if (SUCCEEDED(IWICImagingFactory_CreatePalette(factory, &frame_palette)) && SUCCEEDED(IWICBitmapFrameDecode_CopyPalette(frame, frame_palette))) { IWICPalette_HasAlpha(frame_palette, &frame_palette_has_alpha); } if (SUCCEEDED(IWICImagingFactory_CreatePalette(factory, &global_palette)) && SUCCEEDED(IWICBitmapDecoder_CopyPalette(decoder, global_palette))) { IWICPalette_HasAlpha(global_palette, &global_palette_has_alpha); } has_alpha = frame_palette_has_alpha || global_palette_has_alpha; if (frame_palette != NULL) IUnknown_Release(frame_palette); if (global_palette != NULL) IUnknown_Release(global_palette); } else { has_alpha = IsEqualGUID(MAKE_REFGUID(pixel_format), MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA_)) || IsEqualGUID(MAKE_REFGUID(pixel_format), MAKE_REFGUID(GUID_WICPixelFormat32bppBGRA_)); } return has_alpha; } int ReadPictureWithWIC(const char* const filename, WebPPicture* const pic, int keep_alpha, Metadata* const metadata) { // From Microsoft SDK 6.0a -- ks.h // Define a local copy to avoid link errors under mingw. WEBP_DEFINE_GUID(GUID_NULL_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); static const WICFormatImporter kAlphaFormatImporters[] = { { &GUID_WICPixelFormat32bppBGRA_, 4, WebPPictureImportBGRA }, { &GUID_WICPixelFormat32bppRGBA_, 4, WebPPictureImportRGBA }, { NULL, 0, NULL }, }; static const WICFormatImporter kNonAlphaFormatImporters[] = { { &GUID_WICPixelFormat24bppBGR_, 3, WebPPictureImportBGR }, { &GUID_WICPixelFormat24bppRGB_, 3, WebPPictureImportRGB }, { NULL, 0, NULL }, }; HRESULT hr = S_OK; IWICBitmapFrameDecode* frame = NULL; IWICFormatConverter* converter = NULL; IWICImagingFactory* factory = NULL; IWICBitmapDecoder* decoder = NULL; IStream* stream = NULL; UINT frame_count = 0; UINT width = 0, height = 0; BYTE* rgb = NULL; WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined; const WICFormatImporter* importer = NULL; GUID src_container_format = GUID_NULL_; static const GUID* kAlphaContainers[] = { &GUID_ContainerFormatBmp, &GUID_ContainerFormatPng, &GUID_ContainerFormatTiff, NULL }; int has_alpha = 0; int stride; IFS(CoInitialize(NULL)); IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, CLSCTX_INPROC_SERVER, MAKE_REFGUID(IID_IWICImagingFactory), (LPVOID*)&factory)); if (hr == REGDB_E_CLASSNOTREG) { fprintf(stderr, "Couldn't access Windows Imaging Component (are you running " "Windows XP SP3 or newer?). Most formats not available. " "Use -s for the available YUV input.\n"); } // Prepare for image decoding. IFS(OpenInputStream(filename, &stream)); IFS(IWICImagingFactory_CreateDecoderFromStream( factory, stream, NULL, WICDecodeMetadataCacheOnDemand, &decoder)); IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count)); if (SUCCEEDED(hr) && frame_count == 0) { fprintf(stderr, "No frame found in input file.\n"); hr = E_FAIL; } IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame)); IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format)); IFS(IWICBitmapDecoder_GetContainerFormat(decoder, &src_container_format)); if (keep_alpha) { const GUID** guid; for (guid = kAlphaContainers; *guid != NULL; ++guid) { if (IsEqualGUID(MAKE_REFGUID(src_container_format), MAKE_REFGUID(**guid))) { has_alpha = HasAlpha(factory, decoder, frame, src_pixel_format); break; } } } // Prepare for pixel format conversion (if necessary). IFS(IWICImagingFactory_CreateFormatConverter(factory, &converter)); for (importer = has_alpha ? kAlphaFormatImporters : kNonAlphaFormatImporters; hr == S_OK && importer->import != NULL; ++importer) { BOOL can_convert; const HRESULT cchr = IWICFormatConverter_CanConvert( converter, MAKE_REFGUID(src_pixel_format), MAKE_REFGUID(*importer->pixel_format), &can_convert); if (SUCCEEDED(cchr) && can_convert) break; } if (importer->import == NULL) hr = E_FAIL; IFS(IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame, importer->pixel_format, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom)); // Decode. IFS(IWICFormatConverter_GetSize(converter, &width, &height)); stride = importer->bytes_per_pixel * width * sizeof(*rgb); if (SUCCEEDED(hr)) { rgb = (BYTE*)malloc(stride * height); if (rgb == NULL) hr = E_OUTOFMEMORY; } IFS(IWICFormatConverter_CopyPixels(converter, NULL, stride, stride * height, rgb)); // WebP conversion. if (SUCCEEDED(hr)) { int ok; pic->width = width; pic->height = height; pic->use_argb = 1; ok = importer->import(pic, rgb, stride); if (!ok) hr = E_FAIL; } if (SUCCEEDED(hr)) { if (metadata != NULL) { hr = ExtractMetadata(factory, frame, metadata); if (FAILED(hr)) { fprintf(stderr, "Error extracting image metadata using WIC!\n"); } } } // Cleanup. if (converter != NULL) IUnknown_Release(converter); if (frame != NULL) IUnknown_Release(frame); if (decoder != NULL) IUnknown_Release(decoder); if (factory != NULL) IUnknown_Release(factory); if (stream != NULL) IUnknown_Release(stream); free(rgb); return SUCCEEDED(hr); } #else // !HAVE_WINCODEC_H int ReadPictureWithWIC(const char* const filename, struct WebPPicture* const pic, int keep_alpha, struct Metadata* const metadata) { (void)filename; (void)pic; (void)keep_alpha; (void)metadata; fprintf(stderr, "Windows Imaging Component (WIC) support not compiled. " "Visual Studio and mingw-w64 builds support WIC. Make sure " "wincodec.h detection is working correctly if using autoconf " "and HAVE_WINCODEC_H is defined before building.\n"); return 0; } #endif // HAVE_WINCODEC_H // ----------------------------------------------------------------------------- libwebp-0.4.0/examples/webpmux.c0000644000014400001440000010675312255002107013526 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Simple command-line to create a WebP container file and to extract or strip // relevant data from the container file. // // Authors: Vikas (vikaas.arora@gmail.com), // Urvang (urvang@google.com) /* Usage examples: Create container WebP file: webpmux -frame anim_1.webp +100+10+10 \ -frame anim_2.webp +100+25+25+1 \ -frame anim_3.webp +100+50+50+1 \ -frame anim_4.webp +100 \ -loop 10 -bgcolor 128,255,255,255 \ -o out_animation_container.webp webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp webpmux -set exif image_metadata.exif in.webp -o out_exif_container.webp webpmux -set xmp image_metadata.xmp in.webp -o out_xmp_container.webp Extract relevant data from WebP container file: webpmux -get frgm n in.webp -o out_fragment.webp webpmux -get frame n in.webp -o out_frame.webp webpmux -get icc in.webp -o image_profile.icc webpmux -get exif in.webp -o image_metadata.exif webpmux -get xmp in.webp -o image_metadata.xmp Strip data from WebP Container file: webpmux -strip icc in.webp -o out.webp webpmux -strip exif in.webp -o out.webp webpmux -strip xmp in.webp -o out.webp Misc: webpmux -info in.webp webpmux [ -h | -help ] webpmux -version */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "webp/decode.h" #include "webp/mux.h" #include "./example_util.h" //------------------------------------------------------------------------------ // Config object to parse command-line arguments. typedef enum { NIL_ACTION = 0, ACTION_GET, ACTION_SET, ACTION_STRIP, ACTION_INFO, ACTION_HELP } ActionType; typedef enum { NIL_SUBTYPE = 0, SUBTYPE_ANMF, SUBTYPE_LOOP, SUBTYPE_BGCOLOR } FeatureSubType; typedef struct { FeatureSubType subtype_; const char* filename_; const char* params_; } FeatureArg; typedef enum { NIL_FEATURE = 0, FEATURE_EXIF, FEATURE_XMP, FEATURE_ICCP, FEATURE_ANMF, FEATURE_FRGM, LAST_FEATURE } FeatureType; static const char* const kFourccList[LAST_FEATURE] = { NULL, "EXIF", "XMP ", "ICCP", "ANMF", "FRGM" }; static const char* const kDescriptions[LAST_FEATURE] = { NULL, "EXIF metadata", "XMP metadata", "ICC profile", "Animation frame", "Image fragment" }; typedef struct { FeatureType type_; FeatureArg* args_; int arg_count_; } Feature; typedef struct { ActionType action_type_; const char* input_; const char* output_; Feature feature_; } WebPMuxConfig; //------------------------------------------------------------------------------ // Helper functions. static int CountOccurrences(const char* arglist[], int list_length, const char* arg) { int i; int num_occurences = 0; for (i = 0; i < list_length; ++i) { if (!strcmp(arglist[i], arg)) { ++num_occurences; } } return num_occurences; } static const char* const kErrorMessages[] = { "WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_BAD_DATA", "WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_NOT_ENOUGH_DATA" }; static const char* ErrorString(WebPMuxError err) { assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA); return kErrorMessages[-err]; } #define RETURN_IF_ERROR(ERR_MSG) \ if (err != WEBP_MUX_OK) { \ fprintf(stderr, ERR_MSG); \ return err; \ } #define RETURN_IF_ERROR3(ERR_MSG, FORMAT_STR1, FORMAT_STR2) \ if (err != WEBP_MUX_OK) { \ fprintf(stderr, ERR_MSG, FORMAT_STR1, FORMAT_STR2); \ return err; \ } #define ERROR_GOTO1(ERR_MSG, LABEL) \ do { \ fprintf(stderr, ERR_MSG); \ ok = 0; \ goto LABEL; \ } while (0) #define ERROR_GOTO2(ERR_MSG, FORMAT_STR, LABEL) \ do { \ fprintf(stderr, ERR_MSG, FORMAT_STR); \ ok = 0; \ goto LABEL; \ } while (0) #define ERROR_GOTO3(ERR_MSG, FORMAT_STR1, FORMAT_STR2, LABEL) \ do { \ fprintf(stderr, ERR_MSG, FORMAT_STR1, FORMAT_STR2); \ ok = 0; \ goto LABEL; \ } while (0) static WebPMuxError DisplayInfo(const WebPMux* mux) { int width, height; uint32_t flag; WebPMuxError err = WebPMuxGetCanvasSize(mux, &width, &height); assert(err == WEBP_MUX_OK); // As WebPMuxCreate() was successful earlier. printf("Canvas size: %d x %d\n", width, height); err = WebPMuxGetFeatures(mux, &flag); #ifndef WEBP_EXPERIMENTAL_FEATURES if (flag & FRAGMENTS_FLAG) err = WEBP_MUX_INVALID_ARGUMENT; #endif RETURN_IF_ERROR("Failed to retrieve features\n"); if (flag == 0) { fprintf(stderr, "No features present.\n"); return err; } // Print the features present. printf("Features present:"); if (flag & ANIMATION_FLAG) printf(" animation"); if (flag & FRAGMENTS_FLAG) printf(" image fragments"); if (flag & ICCP_FLAG) printf(" ICC profile"); if (flag & EXIF_FLAG) printf(" EXIF metadata"); if (flag & XMP_FLAG) printf(" XMP metadata"); if (flag & ALPHA_FLAG) printf(" transparency"); printf("\n"); if ((flag & ANIMATION_FLAG) || (flag & FRAGMENTS_FLAG)) { const int is_anim = !!(flag & ANIMATION_FLAG); const WebPChunkId id = is_anim ? WEBP_CHUNK_ANMF : WEBP_CHUNK_FRGM; const char* const type_str = is_anim ? "frame" : "fragment"; int nFrames; if (is_anim) { WebPMuxAnimParams params; err = WebPMuxGetAnimationParams(mux, ¶ms); assert(err == WEBP_MUX_OK); printf("Background color : 0x%.8X Loop Count : %d\n", params.bgcolor, params.loop_count); } err = WebPMuxNumChunks(mux, id, &nFrames); assert(err == WEBP_MUX_OK); printf("Number of %ss: %d\n", type_str, nFrames); if (nFrames > 0) { int i; printf("No.: width height alpha x_offset y_offset "); if (is_anim) printf("duration dispose blend "); printf("image_size\n"); for (i = 1; i <= nFrames; i++) { WebPMuxFrameInfo frame; err = WebPMuxGetFrame(mux, i, &frame); if (err == WEBP_MUX_OK) { WebPBitstreamFeatures features; const VP8StatusCode status = WebPGetFeatures( frame.bitstream.bytes, frame.bitstream.size, &features); assert(status == VP8_STATUS_OK); // Checked by WebPMuxCreate(). (void)status; printf("%3d: %5d %5d %5s %8d %8d ", i, features.width, features.height, features.has_alpha ? "yes" : "no", frame.x_offset, frame.y_offset); if (is_anim) { const char* const dispose = (frame.dispose_method == WEBP_MUX_DISPOSE_NONE) ? "none" : "background"; const char* const blend = (frame.blend_method == WEBP_MUX_BLEND) ? "yes" : "no"; printf("%8d %10s %5s ", frame.duration, dispose, blend); } printf("%10d\n", (int)frame.bitstream.size); } WebPDataClear(&frame.bitstream); RETURN_IF_ERROR3("Failed to retrieve %s#%d\n", type_str, i); } } } if (flag & ICCP_FLAG) { WebPData icc_profile; err = WebPMuxGetChunk(mux, "ICCP", &icc_profile); assert(err == WEBP_MUX_OK); printf("Size of the ICC profile data: %d\n", (int)icc_profile.size); } if (flag & EXIF_FLAG) { WebPData exif; err = WebPMuxGetChunk(mux, "EXIF", &exif); assert(err == WEBP_MUX_OK); printf("Size of the EXIF metadata: %d\n", (int)exif.size); } if (flag & XMP_FLAG) { WebPData xmp; err = WebPMuxGetChunk(mux, "XMP ", &xmp); assert(err == WEBP_MUX_OK); printf("Size of the XMP metadata: %d\n", (int)xmp.size); } if ((flag & ALPHA_FLAG) && !(flag & (ANIMATION_FLAG | FRAGMENTS_FLAG))) { WebPMuxFrameInfo image; err = WebPMuxGetFrame(mux, 1, &image); if (err == WEBP_MUX_OK) { printf("Size of the image (with alpha): %d\n", (int)image.bitstream.size); } WebPDataClear(&image.bitstream); RETURN_IF_ERROR("Failed to retrieve the image\n"); } return WEBP_MUX_OK; } static void PrintHelp(void) { printf("Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT\n"); printf(" webpmux -set SET_OPTIONS INPUT -o OUTPUT\n"); printf(" webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT\n"); #ifdef WEBP_EXPERIMENTAL_FEATURES printf(" webpmux -frgm FRAGMENT_OPTIONS [-frgm...] -o OUTPUT\n"); #endif printf(" webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]" "\n"); printf(" [-bgcolor BACKGROUND_COLOR] -o OUTPUT\n"); printf(" webpmux -info INPUT\n"); printf(" webpmux [-h|-help]\n"); printf(" webpmux -version\n"); printf("\n"); printf("GET_OPTIONS:\n"); printf(" Extract relevant data.\n"); printf(" icc Get ICC profile.\n"); printf(" exif Get EXIF metadata.\n"); printf(" xmp Get XMP metadata.\n"); #ifdef WEBP_EXPERIMENTAL_FEATURES printf(" frgm n Get nth fragment.\n"); #endif printf(" frame n Get nth frame.\n"); printf("\n"); printf("SET_OPTIONS:\n"); printf(" Set color profile/metadata.\n"); printf(" icc file.icc Set ICC profile.\n"); printf(" exif file.exif Set EXIF metadata.\n"); printf(" xmp file.xmp Set XMP metadata.\n"); printf(" where: 'file.icc' contains the ICC profile to be set,\n"); printf(" 'file.exif' contains the EXIF metadata to be set\n"); printf(" 'file.xmp' contains the XMP metadata to be set\n"); printf("\n"); printf("STRIP_OPTIONS:\n"); printf(" Strip color profile/metadata.\n"); printf(" icc Strip ICC profile.\n"); printf(" exif Strip EXIF metadata.\n"); printf(" xmp Strip XMP metadata.\n"); #ifdef WEBP_EXPERIMENTAL_FEATURES printf("\n"); printf("FRAGMENT_OPTIONS(i):\n"); printf(" Create fragmented image.\n"); printf(" file_i +xi+yi\n"); printf(" where: 'file_i' is the i'th fragment (WebP format),\n"); printf(" 'xi','yi' specify the image offset for this fragment." "\n"); #endif printf("\n"); printf("FRAME_OPTIONS(i):\n"); printf(" Create animation.\n"); printf(" file_i +di+[xi+yi[+mi[bi]]]\n"); printf(" where: 'file_i' is the i'th animation frame (WebP format),\n"); printf(" 'di' is the pause duration before next frame.\n"); printf(" 'xi','yi' specify the image offset for this frame.\n"); printf(" 'mi' is the dispose method for this frame (0 or 1).\n"); printf(" 'bi' is the blending method for this frame (+b or -b)." "\n"); printf("\n"); printf("LOOP_COUNT:\n"); printf(" Number of times to repeat the animation.\n"); printf(" Valid range is 0 to 65535 [Default: 0 (infinite)].\n"); printf("\n"); printf("BACKGROUND_COLOR:\n"); printf(" Background color of the canvas.\n"); printf(" A,R,G,B\n"); printf(" where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 " "specifying\n"); printf(" the Alpha, Red, Green and Blue component values " "respectively\n"); printf(" [Default: 255,255,255,255].\n"); printf("\nINPUT & OUTPUT are in WebP format.\n"); printf("\nNote: The nature of EXIF, XMP and ICC data is not checked"); printf(" and is assumed to be\nvalid.\n"); } static int ReadFileToWebPData(const char* const filename, WebPData* const webp_data) { const uint8_t* data; size_t size; if (!ExUtilReadFile(filename, &data, &size)) return 0; webp_data->bytes = data; webp_data->size = size; return 1; } static int CreateMux(const char* const filename, WebPMux** mux) { WebPData bitstream; assert(mux != NULL); if (!ReadFileToWebPData(filename, &bitstream)) return 0; *mux = WebPMuxCreate(&bitstream, 1); free((void*)bitstream.bytes); if (*mux != NULL) return 1; fprintf(stderr, "Failed to create mux object from file %s.\n", filename); return 0; } static int WriteData(const char* filename, const WebPData* const webpdata) { int ok = 0; FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb") : stdout; if (!fout) { fprintf(stderr, "Error opening output WebP file %s!\n", filename); return 0; } if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) { fprintf(stderr, "Error writing file %s!\n", filename); } else { fprintf(stderr, "Saved file %s (%d bytes)\n", filename, (int)webpdata->size); ok = 1; } if (fout != stdout) fclose(fout); return ok; } static int WriteWebP(WebPMux* const mux, const char* filename) { int ok; WebPData webp_data; const WebPMuxError err = WebPMuxAssemble(mux, &webp_data); if (err != WEBP_MUX_OK) { fprintf(stderr, "Error (%s) assembling the WebP file.\n", ErrorString(err)); return 0; } ok = WriteData(filename, &webp_data); WebPDataClear(&webp_data); return ok; } static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) { int dispose_method, dummy; char plus_minus, blend_method; const int num_args = sscanf(args, "+%d+%d+%d+%d%c%c+%d", &info->duration, &info->x_offset, &info->y_offset, &dispose_method, &plus_minus, &blend_method, &dummy); switch (num_args) { case 1: info->x_offset = info->y_offset = 0; // fall through case 3: dispose_method = 0; // fall through case 4: plus_minus = '+'; blend_method = 'b'; // fall through case 6: break; case 2: case 5: default: return 0; } // Note: The sanity of the following conversion is checked by // WebPMuxPushFrame(). info->dispose_method = (WebPMuxAnimDispose)dispose_method; if (blend_method != 'b') return 0; if (plus_minus != '-' && plus_minus != '+') return 0; info->blend_method = (plus_minus == '+') ? WEBP_MUX_BLEND : WEBP_MUX_NO_BLEND; return 1; } static int ParseFragmentArgs(const char* args, WebPMuxFrameInfo* const info) { return (sscanf(args, "+%d+%d", &info->x_offset, &info->y_offset) == 2); } static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) { uint32_t a, r, g, b; if (sscanf(args, "%u,%u,%u,%u", &a, &r, &g, &b) != 4) return 0; if (a >= 256 || r >= 256 || g >= 256 || b >= 256) return 0; *bgcolor = (a << 24) | (r << 16) | (g << 8) | (b << 0); return 1; } //------------------------------------------------------------------------------ // Clean-up. static void DeleteConfig(WebPMuxConfig* config) { if (config != NULL) { free(config->feature_.args_); free(config); } } //------------------------------------------------------------------------------ // Parsing. // Basic syntactic checks on the command-line arguments. // Returns 1 on valid, 0 otherwise. // Also fills up num_feature_args to be number of feature arguments given. // (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5). static int ValidateCommandLine(int argc, const char* argv[], int* num_feature_args) { int num_frame_args; int num_frgm_args; int num_loop_args; int num_bgcolor_args; int ok = 1; assert(num_feature_args != NULL); *num_feature_args = 0; // Simple checks. if (CountOccurrences(argv, argc, "-get") > 1) { ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-set") > 1) { ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-strip") > 1) { ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-info") > 1) { ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate); } if (CountOccurrences(argv, argc, "-o") > 1) { ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate); } // Compound checks. num_frame_args = CountOccurrences(argv, argc, "-frame"); num_frgm_args = CountOccurrences(argv, argc, "-frgm"); num_loop_args = CountOccurrences(argv, argc, "-loop"); num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor"); if (num_loop_args > 1) { ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate); } if (num_bgcolor_args > 1) { ERROR_GOTO1("ERROR: Multiple background colors specified.\n", ErrValidate); } if ((num_frame_args == 0) && (num_loop_args + num_bgcolor_args > 0)) { ERROR_GOTO1("ERROR: Loop count and background color are relevant only in " "case of animation.\n", ErrValidate); } if (num_frame_args > 0 && num_frgm_args > 0) { ERROR_GOTO1("ERROR: Only one of frames & fragments can be specified at a " "time.\n", ErrValidate); } assert(ok == 1); if (num_frame_args == 0 && num_frgm_args == 0) { // Single argument ('set' action for ICCP/EXIF/XMP, OR a 'get' action). *num_feature_args = 1; } else { // Multiple arguments ('set' action for animation or fragmented image). if (num_frame_args > 0) { *num_feature_args = num_frame_args + num_loop_args + num_bgcolor_args; } else { *num_feature_args = num_frgm_args; } } ErrValidate: return ok; } #define ACTION_IS_NIL (config->action_type_ == NIL_ACTION) #define FEATURETYPE_IS_NIL (feature->type_ == NIL_FEATURE) #define CHECK_NUM_ARGS_LESS(NUM, LABEL) \ if (argc < i + (NUM)) { \ fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]); \ goto LABEL; \ } #define CHECK_NUM_ARGS_NOT_EQUAL(NUM, LABEL) \ if (argc != i + (NUM)) { \ fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]); \ goto LABEL; \ } // Parses command-line arguments to fill up config object. Also performs some // semantic checks. static int ParseCommandLine(int argc, const char* argv[], WebPMuxConfig* config) { int i = 0; int feature_arg_index = 0; int ok = 1; while (i < argc) { Feature* const feature = &config->feature_; FeatureArg* const arg = &feature->args_[feature_arg_index]; if (argv[i][0] == '-') { // One of the action types or output. if (!strcmp(argv[i], "-set")) { if (ACTION_IS_NIL) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } ++i; } else if (!strcmp(argv[i], "-get")) { if (ACTION_IS_NIL) { config->action_type_ = ACTION_GET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } ++i; } else if (!strcmp(argv[i], "-strip")) { if (ACTION_IS_NIL) { config->action_type_ = ACTION_STRIP; feature->arg_count_ = 0; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } ++i; } else if (!strcmp(argv[i], "-frame")) { CHECK_NUM_ARGS_LESS(3, ErrParse); if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) { feature->type_ = FEATURE_ANMF; } else { ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse); } arg->subtype_ = SUBTYPE_ANMF; arg->filename_ = argv[i + 1]; arg->params_ = argv[i + 2]; ++feature_arg_index; i += 3; } else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) { CHECK_NUM_ARGS_LESS(2, ErrParse); if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) { feature->type_ = FEATURE_ANMF; } else { ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse); } arg->subtype_ = !strcmp(argv[i], "-loop") ? SUBTYPE_LOOP : SUBTYPE_BGCOLOR; arg->params_ = argv[i + 1]; ++feature_arg_index; i += 2; #ifdef WEBP_EXPERIMENTAL_FEATURES } else if (!strcmp(argv[i], "-frgm")) { CHECK_NUM_ARGS_LESS(3, ErrParse); if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) { config->action_type_ = ACTION_SET; } else { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_FRGM) { feature->type_ = FEATURE_FRGM; } else { ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse); } arg->filename_ = argv[i + 1]; arg->params_ = argv[i + 2]; ++feature_arg_index; i += 3; #endif } else if (!strcmp(argv[i], "-o")) { CHECK_NUM_ARGS_LESS(2, ErrParse); config->output_ = argv[i + 1]; i += 2; } else if (!strcmp(argv[i], "-info")) { CHECK_NUM_ARGS_NOT_EQUAL(2, ErrParse); if (config->action_type_ != NIL_ACTION) { ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse); } else { config->action_type_ = ACTION_INFO; feature->arg_count_ = 0; config->input_ = argv[i + 1]; } i += 2; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) { PrintHelp(); DeleteConfig(config); exit(0); } else if (!strcmp(argv[i], "-version")) { const int version = WebPGetMuxVersion(); printf("%d.%d.%d\n", (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); DeleteConfig(config); exit(0); } else if (!strcmp(argv[i], "--")) { if (i < argc - 1) { ++i; if (config->input_ == NULL) { config->input_ = argv[i]; } else { ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n", argv[i], ErrParse); } } break; } else { ERROR_GOTO2("ERROR: Unknown option: '%s'.\n", argv[i], ErrParse); } } else { // One of the feature types or input. if (ACTION_IS_NIL) { ERROR_GOTO1("ERROR: Action must be specified before other arguments.\n", ErrParse); } if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") || !strcmp(argv[i], "xmp")) { if (FEATURETYPE_IS_NIL) { feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP : (!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP; } else { ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse); } if (config->action_type_ == ACTION_SET) { CHECK_NUM_ARGS_LESS(2, ErrParse); arg->filename_ = argv[i + 1]; ++feature_arg_index; i += 2; } else { ++i; } #ifdef WEBP_EXPERIMENTAL_FEATURES } else if ((!strcmp(argv[i], "frame") || !strcmp(argv[i], "frgm")) && #else } else if (!strcmp(argv[i], "frame") && #endif (config->action_type_ == ACTION_GET)) { CHECK_NUM_ARGS_LESS(2, ErrParse); feature->type_ = (!strcmp(argv[i], "frame")) ? FEATURE_ANMF : FEATURE_FRGM; arg->params_ = argv[i + 1]; ++feature_arg_index; i += 2; } else { // Assume input file. if (config->input_ == NULL) { config->input_ = argv[i]; } else { ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n", argv[i], ErrParse); } ++i; } } } ErrParse: return ok; } // Additional checks after config is filled. static int ValidateConfig(WebPMuxConfig* config) { int ok = 1; Feature* const feature = &config->feature_; // Action. if (ACTION_IS_NIL) { ERROR_GOTO1("ERROR: No action specified.\n", ErrValidate2); } // Feature type. if (FEATURETYPE_IS_NIL && config->action_type_ != ACTION_INFO) { ERROR_GOTO1("ERROR: No feature specified.\n", ErrValidate2); } // Input file. if (config->input_ == NULL) { if (config->action_type_ != ACTION_SET) { ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2); } else if (feature->type_ != FEATURE_ANMF && feature->type_ != FEATURE_FRGM) { ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2); } } // Output file. if (config->output_ == NULL && config->action_type_ != ACTION_INFO) { ERROR_GOTO1("ERROR: No output file specified.\n", ErrValidate2); } ErrValidate2: return ok; } // Create config object from command-line arguments. static int InitializeConfig(int argc, const char* argv[], WebPMuxConfig** config) { int num_feature_args = 0; int ok = 1; assert(config != NULL); *config = NULL; // Validate command-line arguments. if (!ValidateCommandLine(argc, argv, &num_feature_args)) { ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1); } // Allocate memory. *config = (WebPMuxConfig*)calloc(1, sizeof(**config)); if (*config == NULL) { ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1); } (*config)->feature_.arg_count_ = num_feature_args; (*config)->feature_.args_ = (FeatureArg*)calloc(num_feature_args, sizeof(FeatureArg)); if ((*config)->feature_.args_ == NULL) { ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1); } // Parse command-line. if (!ParseCommandLine(argc, argv, *config) || !ValidateConfig(*config)) { ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1); } Err1: return ok; } #undef ACTION_IS_NIL #undef FEATURETYPE_IS_NIL #undef CHECK_NUM_ARGS_LESS #undef CHECK_NUM_ARGS_MORE //------------------------------------------------------------------------------ // Processing. static int GetFrameFragment(const WebPMux* mux, const WebPMuxConfig* config, int is_frame) { WebPMuxError err = WEBP_MUX_OK; WebPMux* mux_single = NULL; long num = 0; int ok = 1; const WebPChunkId id = is_frame ? WEBP_CHUNK_ANMF : WEBP_CHUNK_FRGM; WebPMuxFrameInfo info; WebPDataInit(&info.bitstream); num = strtol(config->feature_.args_[0].params_, NULL, 10); if (num < 0) { ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet); } err = WebPMuxGetFrame(mux, num, &info); if (err == WEBP_MUX_OK && info.id != id) err = WEBP_MUX_NOT_FOUND; if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR (%s): Could not get frame %ld.\n", ErrorString(err), num, ErrGet); } mux_single = WebPMuxNew(); if (mux_single == NULL) { err = WEBP_MUX_MEMORY_ERROR; ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n", ErrorString(err), ErrGet); } err = WebPMuxSetImage(mux_single, &info.bitstream, 1); if (err != WEBP_MUX_OK) { ERROR_GOTO2("ERROR (%s): Could not create single image mux object.\n", ErrorString(err), ErrGet); } ok = WriteWebP(mux_single, config->output_); ErrGet: WebPDataClear(&info.bitstream); WebPMuxDelete(mux_single); return ok; } // Read and process config. static int Process(const WebPMuxConfig* config) { WebPMux* mux = NULL; WebPData chunk; WebPMuxError err = WEBP_MUX_OK; int ok = 1; const Feature* const feature = &config->feature_; switch (config->action_type_) { case ACTION_GET: { ok = CreateMux(config->input_, &mux); if (!ok) goto Err2; switch (feature->type_) { case FEATURE_ANMF: case FEATURE_FRGM: ok = GetFrameFragment(mux, config, (feature->type_ == FEATURE_ANMF) ? 1 : 0); break; case FEATURE_ICCP: case FEATURE_EXIF: case FEATURE_XMP: err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR (%s): Could not get the %s.\n", ErrorString(err), kDescriptions[feature->type_], Err2); } ok = WriteData(config->output_, &chunk); break; default: ERROR_GOTO1("ERROR: Invalid feature for action 'get'.\n", Err2); break; } break; } case ACTION_SET: { switch (feature->type_) { case FEATURE_ANMF: { int i; WebPMuxAnimParams params = { 0xFFFFFFFF, 0 }; mux = WebPMuxNew(); if (mux == NULL) { ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n", ErrorString(WEBP_MUX_MEMORY_ERROR), Err2); } for (i = 0; i < feature->arg_count_; ++i) { switch (feature->args_[i].subtype_) { case SUBTYPE_BGCOLOR: { uint32_t bgcolor; ok = ParseBgcolorArgs(feature->args_[i].params_, &bgcolor); if (!ok) { ERROR_GOTO1("ERROR: Could not parse the background color \n", Err2); } params.bgcolor = bgcolor; break; } case SUBTYPE_LOOP: { const long loop_count = strtol(feature->args_[i].params_, NULL, 10); if (loop_count != (int)loop_count) { // Note: This is only a 'necessary' condition for loop_count // to be valid. The 'sufficient' conditioned in checked in // WebPMuxSetAnimationParams() method called later. ERROR_GOTO1("ERROR: Loop count must be in the range 0 to " "65535.\n", Err2); } params.loop_count = (int)loop_count; break; } case SUBTYPE_ANMF: { WebPMuxFrameInfo frame; frame.id = WEBP_CHUNK_ANMF; ok = ReadFileToWebPData(feature->args_[i].filename_, &frame.bitstream); if (!ok) goto Err2; ok = ParseFrameArgs(feature->args_[i].params_, &frame); if (!ok) { WebPDataClear(&frame.bitstream); ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2); } err = WebPMuxPushFrame(mux, &frame, 1); WebPDataClear(&frame.bitstream); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR (%s): Could not add a frame at index %d." "\n", ErrorString(err), i, Err2); } break; } default: { ERROR_GOTO1("ERROR: Invalid subtype for 'frame'", Err2); break; } } } err = WebPMuxSetAnimationParams(mux, ¶ms); if (err != WEBP_MUX_OK) { ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n", ErrorString(err), Err2); } break; } case FEATURE_FRGM: { int i; mux = WebPMuxNew(); if (mux == NULL) { ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n", ErrorString(WEBP_MUX_MEMORY_ERROR), Err2); } for (i = 0; i < feature->arg_count_; ++i) { WebPMuxFrameInfo frgm; frgm.id = WEBP_CHUNK_FRGM; ok = ReadFileToWebPData(feature->args_[i].filename_, &frgm.bitstream); if (!ok) goto Err2; ok = ParseFragmentArgs(feature->args_[i].params_, &frgm); if (!ok) { WebPDataClear(&frgm.bitstream); ERROR_GOTO1("ERROR: Could not parse fragment properties.\n", Err2); } err = WebPMuxPushFrame(mux, &frgm, 1); WebPDataClear(&frgm.bitstream); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR (%s): Could not add a fragment at index %d.\n", ErrorString(err), i, Err2); } } break; } case FEATURE_ICCP: case FEATURE_EXIF: case FEATURE_XMP: { ok = CreateMux(config->input_, &mux); if (!ok) goto Err2; ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk); if (!ok) goto Err2; err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1); free((void*)chunk.bytes); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR (%s): Could not set the %s.\n", ErrorString(err), kDescriptions[feature->type_], Err2); } break; } default: { ERROR_GOTO1("ERROR: Invalid feature for action 'set'.\n", Err2); break; } } ok = WriteWebP(mux, config->output_); break; } case ACTION_STRIP: { ok = CreateMux(config->input_, &mux); if (!ok) goto Err2; if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF || feature->type_ == FEATURE_XMP) { err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n", ErrorString(err), kDescriptions[feature->type_], Err2); } } else { ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2); break; } ok = WriteWebP(mux, config->output_); break; } case ACTION_INFO: { ok = CreateMux(config->input_, &mux); if (!ok) goto Err2; ok = (DisplayInfo(mux) == WEBP_MUX_OK); break; } default: { assert(0); // Invalid action. break; } } Err2: WebPMuxDelete(mux); return ok; } //------------------------------------------------------------------------------ // Main. int main(int argc, const char* argv[]) { WebPMuxConfig* config; int ok = InitializeConfig(argc - 1, argv + 1, &config); if (ok) { ok = Process(config); } else { PrintHelp(); } DeleteConfig(config); return !ok; } //------------------------------------------------------------------------------ libwebp-0.4.0/examples/Makefile.in0000644000014400001440000012247012255206714013744 0ustar # Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ VPATH = @srcdir@ 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@ target_triplet = @target@ bin_PROGRAMS = dwebp$(EXEEXT) cwebp$(EXEEXT) $(am__EXEEXT_1) \ $(am__EXEEXT_2) $(am__EXEEXT_3) @BUILD_VWEBP_TRUE@am__append_1 = vwebp @WANT_MUX_TRUE@am__append_2 = webpmux @BUILD_GIF2WEBP_TRUE@am__append_3 = gif2webp @BUILD_LIBWEBPDECODER_TRUE@am__append_4 = ../src/libwebpdecoder.la @BUILD_LIBWEBPDECODER_TRUE@am__append_5 = ../src/libwebpdecoder.la @BUILD_LIBWEBPDECODER_FALSE@am__append_6 = ../src/libwebp.la @BUILD_LIBWEBPDECODER_FALSE@am__append_7 = ../src/libwebp.la subdir = examples DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libexampleutil_la_LIBADD = am_libexampleutil_la_OBJECTS = example_util.lo libexampleutil_la_OBJECTS = $(am_libexampleutil_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @BUILD_VWEBP_TRUE@am__EXEEXT_1 = vwebp$(EXEEXT) @WANT_MUX_TRUE@am__EXEEXT_2 = webpmux$(EXEEXT) @BUILD_GIF2WEBP_TRUE@am__EXEEXT_3 = gif2webp$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cwebp_OBJECTS = cwebp-cwebp.$(OBJEXT) cwebp-metadata.$(OBJEXT) \ cwebp-jpegdec.$(OBJEXT) cwebp-pngdec.$(OBJEXT) \ cwebp-tiffdec.$(OBJEXT) cwebp-wicdec.$(OBJEXT) cwebp_OBJECTS = $(am_cwebp_OBJECTS) am__DEPENDENCIES_1 = cwebp_DEPENDENCIES = ../src/libwebp.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_dwebp_OBJECTS = dwebp-dwebp.$(OBJEXT) dwebp_OBJECTS = $(am_dwebp_OBJECTS) dwebp_DEPENDENCIES = libexampleutil.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__append_4) $(am__append_6) am_gif2webp_OBJECTS = gif2webp-gif2webp.$(OBJEXT) \ gif2webp-gif2webp_util.$(OBJEXT) gif2webp_OBJECTS = $(am_gif2webp_OBJECTS) gif2webp_DEPENDENCIES = libexampleutil.la ../src/mux/libwebpmux.la \ ../src/libwebp.la $(am__DEPENDENCIES_1) am_vwebp_OBJECTS = vwebp-vwebp.$(OBJEXT) vwebp_OBJECTS = $(am_vwebp_OBJECTS) vwebp_DEPENDENCIES = libexampleutil.la ../src/demux/libwebpdemux.la \ $(am__DEPENDENCIES_1) $(am__append_5) $(am__append_7) am_webpmux_OBJECTS = webpmux-webpmux.$(OBJEXT) webpmux_OBJECTS = $(am_webpmux_OBJECTS) webpmux_DEPENDENCIES = libexampleutil.la ../src/mux/libwebpmux.la \ ../src/libwebp.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles 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_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ 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_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libexampleutil_la_SOURCES) $(cwebp_SOURCES) \ $(dwebp_SOURCES) $(gif2webp_SOURCES) $(vwebp_SOURCES) \ $(webpmux_SOURCES) DIST_SOURCES = $(libexampleutil_la_SOURCES) $(cwebp_SOURCES) \ $(dwebp_SOURCES) $(gif2webp_SOURCES) $(vwebp_SOURCES) \ $(webpmux_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GIF_INCLUDES = @GIF_INCLUDES@ GIF_LIBS = @GIF_LIBS@ GL_INCLUDES = @GL_INCLUDES@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JPEG_INCLUDES = @JPEG_INCLUDES@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBPNG_CONFIG = @LIBPNG_CONFIG@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNG_INCLUDES = @PNG_INCLUDES@ PNG_LIBS = @PNG_LIBS@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TIFF_INCLUDES = @TIFF_INCLUDES@ TIFF_LIBS = @TIFF_LIBS@ USE_EXPERIMENTAL_CODE = @USE_EXPERIMENTAL_CODE@ USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ VERSION = @VERSION@ 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_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@ ax_pthread_config = @ax_pthread_config@ 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@ 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@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/src noinst_LTLIBRARIES = libexampleutil.la libexampleutil_la_SOURCES = example_util.c example_util.h dwebp_SOURCES = dwebp.c stopwatch.h dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) \ $(JPEG_INCLUDES) $(PNG_INCLUDES) dwebp_LDADD = libexampleutil.la $(PNG_LIBS) $(JPEG_LIBS) \ $(am__append_4) $(am__append_6) cwebp_SOURCES = cwebp.c metadata.c metadata.h stopwatch.h jpegdec.c \ jpegdec.h pngdec.c pngdec.h tiffdec.c tiffdec.h wicdec.c \ wicdec.h cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) \ $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES) cwebp_LDADD = ../src/libwebp.la $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS) gif2webp_SOURCES = gif2webp.c gif2webp_util.c gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES) gif2webp_LDADD = libexampleutil.la ../src/mux/libwebpmux.la \ ../src/libwebp.la $(GIF_LIBS) webpmux_SOURCES = webpmux.c webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) webpmux_LDADD = libexampleutil.la ../src/mux/libwebpmux.la ../src/libwebp.la vwebp_SOURCES = vwebp.c vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES) vwebp_LDADD = libexampleutil.la ../src/demux/libwebpdemux.la \ $(GL_LIBS) $(am__append_5) $(am__append_7) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libexampleutil.la: $(libexampleutil_la_OBJECTS) $(libexampleutil_la_DEPENDENCIES) $(EXTRA_libexampleutil_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libexampleutil_la_OBJECTS) $(libexampleutil_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ 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)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || 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)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_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 cwebp$(EXEEXT): $(cwebp_OBJECTS) $(cwebp_DEPENDENCIES) $(EXTRA_cwebp_DEPENDENCIES) @rm -f cwebp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cwebp_OBJECTS) $(cwebp_LDADD) $(LIBS) dwebp$(EXEEXT): $(dwebp_OBJECTS) $(dwebp_DEPENDENCIES) $(EXTRA_dwebp_DEPENDENCIES) @rm -f dwebp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(dwebp_OBJECTS) $(dwebp_LDADD) $(LIBS) gif2webp$(EXEEXT): $(gif2webp_OBJECTS) $(gif2webp_DEPENDENCIES) $(EXTRA_gif2webp_DEPENDENCIES) @rm -f gif2webp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gif2webp_OBJECTS) $(gif2webp_LDADD) $(LIBS) vwebp$(EXEEXT): $(vwebp_OBJECTS) $(vwebp_DEPENDENCIES) $(EXTRA_vwebp_DEPENDENCIES) @rm -f vwebp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vwebp_OBJECTS) $(vwebp_LDADD) $(LIBS) webpmux$(EXEEXT): $(webpmux_OBJECTS) $(webpmux_DEPENDENCIES) $(EXTRA_webpmux_DEPENDENCIES) @rm -f webpmux$(EXEEXT) $(AM_V_CCLD)$(LINK) $(webpmux_OBJECTS) $(webpmux_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebp-cwebp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebp-jpegdec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebp-metadata.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebp-pngdec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebp-tiffdec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebp-wicdec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwebp-dwebp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gif2webp-gif2webp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gif2webp-gif2webp_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vwebp-vwebp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/webpmux-webpmux.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 $@ $< cwebp-cwebp.o: cwebp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-cwebp.o -MD -MP -MF $(DEPDIR)/cwebp-cwebp.Tpo -c -o cwebp-cwebp.o `test -f 'cwebp.c' || echo '$(srcdir)/'`cwebp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-cwebp.Tpo $(DEPDIR)/cwebp-cwebp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cwebp.c' object='cwebp-cwebp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-cwebp.o `test -f 'cwebp.c' || echo '$(srcdir)/'`cwebp.c cwebp-cwebp.obj: cwebp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-cwebp.obj -MD -MP -MF $(DEPDIR)/cwebp-cwebp.Tpo -c -o cwebp-cwebp.obj `if test -f 'cwebp.c'; then $(CYGPATH_W) 'cwebp.c'; else $(CYGPATH_W) '$(srcdir)/cwebp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-cwebp.Tpo $(DEPDIR)/cwebp-cwebp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cwebp.c' object='cwebp-cwebp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-cwebp.obj `if test -f 'cwebp.c'; then $(CYGPATH_W) 'cwebp.c'; else $(CYGPATH_W) '$(srcdir)/cwebp.c'; fi` cwebp-metadata.o: metadata.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-metadata.o -MD -MP -MF $(DEPDIR)/cwebp-metadata.Tpo -c -o cwebp-metadata.o `test -f 'metadata.c' || echo '$(srcdir)/'`metadata.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-metadata.Tpo $(DEPDIR)/cwebp-metadata.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='metadata.c' object='cwebp-metadata.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-metadata.o `test -f 'metadata.c' || echo '$(srcdir)/'`metadata.c cwebp-metadata.obj: metadata.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-metadata.obj -MD -MP -MF $(DEPDIR)/cwebp-metadata.Tpo -c -o cwebp-metadata.obj `if test -f 'metadata.c'; then $(CYGPATH_W) 'metadata.c'; else $(CYGPATH_W) '$(srcdir)/metadata.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-metadata.Tpo $(DEPDIR)/cwebp-metadata.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='metadata.c' object='cwebp-metadata.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-metadata.obj `if test -f 'metadata.c'; then $(CYGPATH_W) 'metadata.c'; else $(CYGPATH_W) '$(srcdir)/metadata.c'; fi` cwebp-jpegdec.o: jpegdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-jpegdec.o -MD -MP -MF $(DEPDIR)/cwebp-jpegdec.Tpo -c -o cwebp-jpegdec.o `test -f 'jpegdec.c' || echo '$(srcdir)/'`jpegdec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-jpegdec.Tpo $(DEPDIR)/cwebp-jpegdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jpegdec.c' object='cwebp-jpegdec.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-jpegdec.o `test -f 'jpegdec.c' || echo '$(srcdir)/'`jpegdec.c cwebp-jpegdec.obj: jpegdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-jpegdec.obj -MD -MP -MF $(DEPDIR)/cwebp-jpegdec.Tpo -c -o cwebp-jpegdec.obj `if test -f 'jpegdec.c'; then $(CYGPATH_W) 'jpegdec.c'; else $(CYGPATH_W) '$(srcdir)/jpegdec.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-jpegdec.Tpo $(DEPDIR)/cwebp-jpegdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jpegdec.c' object='cwebp-jpegdec.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-jpegdec.obj `if test -f 'jpegdec.c'; then $(CYGPATH_W) 'jpegdec.c'; else $(CYGPATH_W) '$(srcdir)/jpegdec.c'; fi` cwebp-pngdec.o: pngdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-pngdec.o -MD -MP -MF $(DEPDIR)/cwebp-pngdec.Tpo -c -o cwebp-pngdec.o `test -f 'pngdec.c' || echo '$(srcdir)/'`pngdec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-pngdec.Tpo $(DEPDIR)/cwebp-pngdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pngdec.c' object='cwebp-pngdec.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-pngdec.o `test -f 'pngdec.c' || echo '$(srcdir)/'`pngdec.c cwebp-pngdec.obj: pngdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-pngdec.obj -MD -MP -MF $(DEPDIR)/cwebp-pngdec.Tpo -c -o cwebp-pngdec.obj `if test -f 'pngdec.c'; then $(CYGPATH_W) 'pngdec.c'; else $(CYGPATH_W) '$(srcdir)/pngdec.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-pngdec.Tpo $(DEPDIR)/cwebp-pngdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pngdec.c' object='cwebp-pngdec.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-pngdec.obj `if test -f 'pngdec.c'; then $(CYGPATH_W) 'pngdec.c'; else $(CYGPATH_W) '$(srcdir)/pngdec.c'; fi` cwebp-tiffdec.o: tiffdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-tiffdec.o -MD -MP -MF $(DEPDIR)/cwebp-tiffdec.Tpo -c -o cwebp-tiffdec.o `test -f 'tiffdec.c' || echo '$(srcdir)/'`tiffdec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-tiffdec.Tpo $(DEPDIR)/cwebp-tiffdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tiffdec.c' object='cwebp-tiffdec.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-tiffdec.o `test -f 'tiffdec.c' || echo '$(srcdir)/'`tiffdec.c cwebp-tiffdec.obj: tiffdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-tiffdec.obj -MD -MP -MF $(DEPDIR)/cwebp-tiffdec.Tpo -c -o cwebp-tiffdec.obj `if test -f 'tiffdec.c'; then $(CYGPATH_W) 'tiffdec.c'; else $(CYGPATH_W) '$(srcdir)/tiffdec.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-tiffdec.Tpo $(DEPDIR)/cwebp-tiffdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tiffdec.c' object='cwebp-tiffdec.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-tiffdec.obj `if test -f 'tiffdec.c'; then $(CYGPATH_W) 'tiffdec.c'; else $(CYGPATH_W) '$(srcdir)/tiffdec.c'; fi` cwebp-wicdec.o: wicdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-wicdec.o -MD -MP -MF $(DEPDIR)/cwebp-wicdec.Tpo -c -o cwebp-wicdec.o `test -f 'wicdec.c' || echo '$(srcdir)/'`wicdec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-wicdec.Tpo $(DEPDIR)/cwebp-wicdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wicdec.c' object='cwebp-wicdec.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-wicdec.o `test -f 'wicdec.c' || echo '$(srcdir)/'`wicdec.c cwebp-wicdec.obj: wicdec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cwebp-wicdec.obj -MD -MP -MF $(DEPDIR)/cwebp-wicdec.Tpo -c -o cwebp-wicdec.obj `if test -f 'wicdec.c'; then $(CYGPATH_W) 'wicdec.c'; else $(CYGPATH_W) '$(srcdir)/wicdec.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cwebp-wicdec.Tpo $(DEPDIR)/cwebp-wicdec.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wicdec.c' object='cwebp-wicdec.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cwebp-wicdec.obj `if test -f 'wicdec.c'; then $(CYGPATH_W) 'wicdec.c'; else $(CYGPATH_W) '$(srcdir)/wicdec.c'; fi` dwebp-dwebp.o: dwebp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dwebp-dwebp.o -MD -MP -MF $(DEPDIR)/dwebp-dwebp.Tpo -c -o dwebp-dwebp.o `test -f 'dwebp.c' || echo '$(srcdir)/'`dwebp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwebp-dwebp.Tpo $(DEPDIR)/dwebp-dwebp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwebp.c' object='dwebp-dwebp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dwebp-dwebp.o `test -f 'dwebp.c' || echo '$(srcdir)/'`dwebp.c dwebp-dwebp.obj: dwebp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dwebp-dwebp.obj -MD -MP -MF $(DEPDIR)/dwebp-dwebp.Tpo -c -o dwebp-dwebp.obj `if test -f 'dwebp.c'; then $(CYGPATH_W) 'dwebp.c'; else $(CYGPATH_W) '$(srcdir)/dwebp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwebp-dwebp.Tpo $(DEPDIR)/dwebp-dwebp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwebp.c' object='dwebp-dwebp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dwebp-dwebp.obj `if test -f 'dwebp.c'; then $(CYGPATH_W) 'dwebp.c'; else $(CYGPATH_W) '$(srcdir)/dwebp.c'; fi` gif2webp-gif2webp.o: gif2webp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gif2webp-gif2webp.o -MD -MP -MF $(DEPDIR)/gif2webp-gif2webp.Tpo -c -o gif2webp-gif2webp.o `test -f 'gif2webp.c' || echo '$(srcdir)/'`gif2webp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gif2webp-gif2webp.Tpo $(DEPDIR)/gif2webp-gif2webp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gif2webp.c' object='gif2webp-gif2webp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gif2webp-gif2webp.o `test -f 'gif2webp.c' || echo '$(srcdir)/'`gif2webp.c gif2webp-gif2webp.obj: gif2webp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gif2webp-gif2webp.obj -MD -MP -MF $(DEPDIR)/gif2webp-gif2webp.Tpo -c -o gif2webp-gif2webp.obj `if test -f 'gif2webp.c'; then $(CYGPATH_W) 'gif2webp.c'; else $(CYGPATH_W) '$(srcdir)/gif2webp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gif2webp-gif2webp.Tpo $(DEPDIR)/gif2webp-gif2webp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gif2webp.c' object='gif2webp-gif2webp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gif2webp-gif2webp.obj `if test -f 'gif2webp.c'; then $(CYGPATH_W) 'gif2webp.c'; else $(CYGPATH_W) '$(srcdir)/gif2webp.c'; fi` gif2webp-gif2webp_util.o: gif2webp_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gif2webp-gif2webp_util.o -MD -MP -MF $(DEPDIR)/gif2webp-gif2webp_util.Tpo -c -o gif2webp-gif2webp_util.o `test -f 'gif2webp_util.c' || echo '$(srcdir)/'`gif2webp_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gif2webp-gif2webp_util.Tpo $(DEPDIR)/gif2webp-gif2webp_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gif2webp_util.c' object='gif2webp-gif2webp_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gif2webp-gif2webp_util.o `test -f 'gif2webp_util.c' || echo '$(srcdir)/'`gif2webp_util.c gif2webp-gif2webp_util.obj: gif2webp_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gif2webp-gif2webp_util.obj -MD -MP -MF $(DEPDIR)/gif2webp-gif2webp_util.Tpo -c -o gif2webp-gif2webp_util.obj `if test -f 'gif2webp_util.c'; then $(CYGPATH_W) 'gif2webp_util.c'; else $(CYGPATH_W) '$(srcdir)/gif2webp_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gif2webp-gif2webp_util.Tpo $(DEPDIR)/gif2webp-gif2webp_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gif2webp_util.c' object='gif2webp-gif2webp_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gif2webp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gif2webp-gif2webp_util.obj `if test -f 'gif2webp_util.c'; then $(CYGPATH_W) 'gif2webp_util.c'; else $(CYGPATH_W) '$(srcdir)/gif2webp_util.c'; fi` vwebp-vwebp.o: vwebp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vwebp-vwebp.o -MD -MP -MF $(DEPDIR)/vwebp-vwebp.Tpo -c -o vwebp-vwebp.o `test -f 'vwebp.c' || echo '$(srcdir)/'`vwebp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vwebp-vwebp.Tpo $(DEPDIR)/vwebp-vwebp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vwebp.c' object='vwebp-vwebp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vwebp-vwebp.o `test -f 'vwebp.c' || echo '$(srcdir)/'`vwebp.c vwebp-vwebp.obj: vwebp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vwebp-vwebp.obj -MD -MP -MF $(DEPDIR)/vwebp-vwebp.Tpo -c -o vwebp-vwebp.obj `if test -f 'vwebp.c'; then $(CYGPATH_W) 'vwebp.c'; else $(CYGPATH_W) '$(srcdir)/vwebp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vwebp-vwebp.Tpo $(DEPDIR)/vwebp-vwebp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vwebp.c' object='vwebp-vwebp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vwebp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vwebp-vwebp.obj `if test -f 'vwebp.c'; then $(CYGPATH_W) 'vwebp.c'; else $(CYGPATH_W) '$(srcdir)/vwebp.c'; fi` webpmux-webpmux.o: webpmux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(webpmux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT webpmux-webpmux.o -MD -MP -MF $(DEPDIR)/webpmux-webpmux.Tpo -c -o webpmux-webpmux.o `test -f 'webpmux.c' || echo '$(srcdir)/'`webpmux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/webpmux-webpmux.Tpo $(DEPDIR)/webpmux-webpmux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='webpmux.c' object='webpmux-webpmux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(webpmux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o webpmux-webpmux.o `test -f 'webpmux.c' || echo '$(srcdir)/'`webpmux.c webpmux-webpmux.obj: webpmux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(webpmux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT webpmux-webpmux.obj -MD -MP -MF $(DEPDIR)/webpmux-webpmux.Tpo -c -o webpmux-webpmux.obj `if test -f 'webpmux.c'; then $(CYGPATH_W) 'webpmux.c'; else $(CYGPATH_W) '$(srcdir)/webpmux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/webpmux-webpmux.Tpo $(DEPDIR)/webpmux-webpmux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='webpmux.c' object='webpmux-webpmux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(webpmux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o webpmux-webpmux.obj `if test -f 'webpmux.c'; then $(CYGPATH_W) 'webpmux.c'; else $(CYGPATH_W) '$(srcdir)/webpmux.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ 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" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; 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-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-binPROGRAMS 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 -rf ./$(DEPDIR) -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-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-noinstLTLIBRARIES ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ 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-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 uninstall uninstall-am uninstall-binPROGRAMS # 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: libwebp-0.4.0/examples/stopwatch.h0000644000014400001440000000320412255002107014043 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Helper functions to measure elapsed time. // // Author: Mikolaj Zalewski (mikolajz@google.com) #ifndef WEBP_EXAMPLES_STOPWATCH_H_ #define WEBP_EXAMPLES_STOPWATCH_H_ #if defined _WIN32 && !defined __GNUC__ #include typedef LARGE_INTEGER Stopwatch; static WEBP_INLINE void StopwatchReset(Stopwatch* watch) { QueryPerformanceCounter(watch); } static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) { const LARGE_INTEGER old_value = *watch; LARGE_INTEGER freq; if (!QueryPerformanceCounter(watch)) return 0.0; if (!QueryPerformanceFrequency(&freq)) return 0.0; if (freq.QuadPart == 0) return 0.0; return (watch->QuadPart - old_value.QuadPart) / (double)freq.QuadPart; } #else /* !_WIN32 */ #include typedef struct timeval Stopwatch; static WEBP_INLINE void StopwatchReset(Stopwatch* watch) { gettimeofday(watch, NULL); } static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) { const struct timeval old_value = *watch; gettimeofday(watch, NULL); return watch->tv_sec - old_value.tv_sec + (watch->tv_usec - old_value.tv_usec) / 1000000.0; } #endif /* _WIN32 */ #endif /* WEBP_EXAMPLES_STOPWATCH_H_ */ libwebp-0.4.0/examples/vwebp.c0000644000014400001440000004046012255002107013152 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Simple OpenGL-based WebP file viewer. // // Author: Skal (pascal.massimino@gmail.com) #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #if defined(WEBP_HAVE_GL) #if defined(HAVE_GLUT_GLUT_H) #include #else #include #ifdef FREEGLUT #include #endif #endif #ifdef WEBP_HAVE_QCMS #include #endif #include "webp/decode.h" #include "webp/demux.h" #include "./example_util.h" #ifdef _MSC_VER #define snprintf _snprintf #endif static void Help(void); // Unfortunate global variables. Gathered into a struct for comfort. static struct { int has_animation; int has_color_profile; int done; int decoding_error; int print_info; int use_color_profile; int canvas_width, canvas_height; int loop_count; uint32_t bg_color; const char* file_name; WebPData data; WebPDecoderConfig config; const WebPDecBuffer* pic; WebPDemuxer* dmux; WebPIterator curr_frame; WebPIterator prev_frame; WebPChunkIterator iccp; } kParams; static void ClearPreviousPic(void) { WebPFreeDecBuffer((WebPDecBuffer*)kParams.pic); kParams.pic = NULL; } static void ClearParams(void) { ClearPreviousPic(); WebPDataClear(&kParams.data); WebPDemuxReleaseIterator(&kParams.curr_frame); WebPDemuxReleaseIterator(&kParams.prev_frame); WebPDemuxReleaseChunkIterator(&kParams.iccp); WebPDemuxDelete(kParams.dmux); kParams.dmux = NULL; } // ----------------------------------------------------------------------------- // Color profile handling static int ApplyColorProfile(const WebPData* const profile, WebPDecBuffer* const rgba) { #ifdef WEBP_HAVE_QCMS int i, ok = 0; uint8_t* line; uint8_t major_revision; qcms_profile* input_profile = NULL; qcms_profile* output_profile = NULL; qcms_transform* transform = NULL; const qcms_data_type input_type = QCMS_DATA_RGBA_8; const qcms_data_type output_type = QCMS_DATA_RGBA_8; const qcms_intent intent = QCMS_INTENT_DEFAULT; if (profile == NULL || rgba == NULL) return 0; if (profile->bytes == NULL || profile->size < 10) return 1; major_revision = profile->bytes[8]; qcms_enable_iccv4(); input_profile = qcms_profile_from_memory(profile->bytes, profile->size); // qcms_profile_is_bogus() is broken with ICCv4. if (input_profile == NULL || (major_revision < 4 && qcms_profile_is_bogus(input_profile))) { fprintf(stderr, "Color profile is bogus!\n"); goto Error; } output_profile = qcms_profile_sRGB(); if (output_profile == NULL) { fprintf(stderr, "Error creating output color profile!\n"); goto Error; } qcms_profile_precache_output_transform(output_profile); transform = qcms_transform_create(input_profile, input_type, output_profile, output_type, intent); if (transform == NULL) { fprintf(stderr, "Error creating color transform!\n"); goto Error; } line = rgba->u.RGBA.rgba; for (i = 0; i < rgba->height; ++i, line += rgba->u.RGBA.stride) { qcms_transform_data(transform, line, line, rgba->width); } ok = 1; Error: if (input_profile != NULL) qcms_profile_release(input_profile); if (output_profile != NULL) qcms_profile_release(output_profile); if (transform != NULL) qcms_transform_release(transform); return ok; #else (void)profile; (void)rgba; return 1; #endif // WEBP_HAVE_QCMS } //------------------------------------------------------------------------------ // File decoding static int Decode(void) { // Fills kParams.curr_frame const WebPIterator* const curr = &kParams.curr_frame; WebPDecoderConfig* const config = &kParams.config; WebPDecBuffer* const output_buffer = &config->output; int ok = 0; ClearPreviousPic(); output_buffer->colorspace = MODE_RGBA; ok = (WebPDecode(curr->fragment.bytes, curr->fragment.size, config) == VP8_STATUS_OK); if (!ok) { fprintf(stderr, "Decoding of frame #%d failed!\n", curr->frame_num); } else { kParams.pic = output_buffer; if (kParams.use_color_profile) { ok = ApplyColorProfile(&kParams.iccp.chunk, output_buffer); if (!ok) { fprintf(stderr, "Applying color profile to frame #%d failed!\n", curr->frame_num); } } } return ok; } static void decode_callback(int what) { if (what == 0 && !kParams.done) { int duration = 0; if (kParams.dmux != NULL) { WebPIterator* const curr = &kParams.curr_frame; if (!WebPDemuxNextFrame(curr)) { WebPDemuxReleaseIterator(curr); if (WebPDemuxGetFrame(kParams.dmux, 1, curr)) { --kParams.loop_count; kParams.done = (kParams.loop_count == 0); } else { kParams.decoding_error = 1; kParams.done = 1; return; } } duration = curr->duration; } if (!Decode()) { kParams.decoding_error = 1; kParams.done = 1; } else { glutPostRedisplay(); glutTimerFunc(duration, decode_callback, what); } } } //------------------------------------------------------------------------------ // Callbacks static void HandleKey(unsigned char key, int pos_x, int pos_y) { (void)pos_x; (void)pos_y; if (key == 'q' || key == 'Q' || key == 27 /* Esc */) { #ifdef FREEGLUT glutLeaveMainLoop(); #else ClearParams(); exit(0); #endif } else if (key == 'c') { if (kParams.has_color_profile && !kParams.decoding_error) { kParams.use_color_profile = 1 - kParams.use_color_profile; if (kParams.has_animation) { // Restart the completed animation to pickup the color profile change. if (kParams.done && kParams.loop_count == 0) { kParams.loop_count = (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT) + 1; kParams.done = 0; // Start the decode loop immediately. glutTimerFunc(0, decode_callback, 0); } } else { Decode(); glutPostRedisplay(); } } } else if (key == 'i') { kParams.print_info = 1 - kParams.print_info; glutPostRedisplay(); } } static void HandleReshape(int width, int height) { // TODO(skal): proper handling of resize, esp. for large pictures. // + key control of the zoom. glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static void PrintString(const char* const text) { void* const font = GLUT_BITMAP_9_BY_15; int i; for (i = 0; text[i]; ++i) { glutBitmapCharacter(font, text[i]); } } static float GetColorf(uint32_t color, int shift) { return (color >> shift) / 255.f; } static void DrawCheckerBoard(void) { const int square_size = 8; // must be a power of 2 int x, y; GLint viewport[4]; // x, y, width, height glPushMatrix(); glGetIntegerv(GL_VIEWPORT, viewport); // shift to integer coordinates with (0,0) being top-left. glOrtho(0, viewport[2], viewport[3], 0, -1, 1); for (y = 0; y < viewport[3]; y += square_size) { for (x = 0; x < viewport[2]; x += square_size) { const GLubyte color = 128 + 64 * (!((x + y) & square_size)); glColor3ub(color, color, color); glRecti(x, y, x + square_size, y + square_size); } } glPopMatrix(); } static void HandleDisplay(void) { const WebPDecBuffer* const pic = kParams.pic; const WebPIterator* const curr = &kParams.curr_frame; WebPIterator* const prev = &kParams.prev_frame; GLfloat xoff, yoff; if (pic == NULL) return; glPushMatrix(); glPixelZoom(1, -1); xoff = (GLfloat)(2. * curr->x_offset / kParams.canvas_width); yoff = (GLfloat)(2. * curr->y_offset / kParams.canvas_height); glRasterPos2f(-1.f + xoff, 1.f - yoff); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4); if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND || curr->blend_method == WEBP_MUX_NO_BLEND) { // TODO(later): these offsets and those above should factor in window size. // they will be incorrect if the window is resized. // glScissor() takes window coordinates (0,0 at bottom left). int window_x, window_y; if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { // Clear the previous frame rectangle. window_x = prev->x_offset; window_y = kParams.canvas_height - prev->y_offset - prev->height; } else { // curr->blend_method == WEBP_MUX_NO_BLEND. // We simulate no-blending behavior by first clearing the current frame // rectangle (to a checker-board) and then alpha-blending against it. window_x = curr->x_offset; window_y = kParams.canvas_height - curr->y_offset - curr->height; } glEnable(GL_SCISSOR_TEST); // Only update the requested area, not the whole canvas. glScissor(window_x, window_y, prev->width, prev->height); glClear(GL_COLOR_BUFFER_BIT); // use clear color DrawCheckerBoard(); glDisable(GL_SCISSOR_TEST); } *prev = *curr; glDrawPixels(pic->width, pic->height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pic->u.RGBA.rgba); if (kParams.print_info) { char tmp[32]; glColor4f(0.90f, 0.0f, 0.90f, 1.0f); glRasterPos2f(-0.95f, 0.90f); PrintString(kParams.file_name); snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height); glColor4f(0.90f, 0.0f, 0.90f, 1.0f); glRasterPos2f(-0.95f, 0.80f); PrintString(tmp); if (curr->x_offset != 0 || curr->y_offset != 0) { snprintf(tmp, sizeof(tmp), " (offset:%d,%d)", curr->x_offset, curr->y_offset); glRasterPos2f(-0.95f, 0.70f); PrintString(tmp); } } glPopMatrix(); glFlush(); } static void StartDisplay(void) { const int width = kParams.canvas_width; const int height = kParams.canvas_height; glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(width, height); glutCreateWindow("WebP viewer"); glutDisplayFunc(HandleDisplay); glutIdleFunc(NULL); glutKeyboardFunc(HandleKey); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glClearColor(GetColorf(kParams.bg_color, 0), GetColorf(kParams.bg_color, 8), GetColorf(kParams.bg_color, 16), GetColorf(kParams.bg_color, 24)); HandleReshape(width, height); glClear(GL_COLOR_BUFFER_BIT); DrawCheckerBoard(); } //------------------------------------------------------------------------------ // Main static void Help(void) { printf("Usage: vwebp in_file [options]\n\n" "Decodes the WebP image file and visualize it using OpenGL\n" "Options are:\n" " -version .... print version number and exit.\n" " -noicc ....... don't use the icc profile if present.\n" " -nofancy ..... don't use the fancy YUV420 upscaler.\n" " -nofilter .... disable in-loop filtering.\n" " -dither dithering strength (0..100). Default=50.\n" " -mt .......... use multi-threading.\n" " -info ........ print info.\n" " -h ....... this help message.\n" "\n" "Keyboard shortcuts:\n" " 'c' ................ toggle use of color profile.\n" " 'i' ................ overlay file information.\n" " 'q' / 'Q' / ESC .... quit.\n" ); } int main(int argc, char *argv[]) { int c; WebPDecoderConfig* const config = &kParams.config; WebPIterator* const curr = &kParams.curr_frame; WebPIterator* const prev = &kParams.prev_frame; if (!WebPInitDecoderConfig(config)) { fprintf(stderr, "Library version mismatch!\n"); return -1; } config->options.dithering_strength = 50; kParams.use_color_profile = 1; for (c = 1; c < argc; ++c) { if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { Help(); return 0; } else if (!strcmp(argv[c], "-noicc")) { kParams.use_color_profile = 0; } else if (!strcmp(argv[c], "-nofancy")) { config->options.no_fancy_upsampling = 1; } else if (!strcmp(argv[c], "-nofilter")) { config->options.bypass_filtering = 1; } else if (!strcmp(argv[c], "-dither") && c + 1 < argc) { config->options.dithering_strength = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-info")) { kParams.print_info = 1; } else if (!strcmp(argv[c], "-version")) { const int dec_version = WebPGetDecoderVersion(); const int dmux_version = WebPGetDemuxVersion(); printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n", (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff, dec_version & 0xff, (dmux_version >> 16) & 0xff, (dmux_version >> 8) & 0xff, dmux_version & 0xff); return 0; } else if (!strcmp(argv[c], "-mt")) { config->options.use_threads = 1; } else if (!strcmp(argv[c], "--")) { if (c < argc - 1) kParams.file_name = argv[++c]; break; } else if (argv[c][0] == '-') { printf("Unknown option '%s'\n", argv[c]); Help(); return -1; } else { kParams.file_name = argv[c]; } } if (kParams.file_name == NULL) { printf("missing input file!!\n"); Help(); return 0; } if (!ExUtilReadFile(kParams.file_name, &kParams.data.bytes, &kParams.data.size)) { goto Error; } if (!WebPGetInfo(kParams.data.bytes, kParams.data.size, NULL, NULL)) { fprintf(stderr, "Input file doesn't appear to be WebP format.\n"); goto Error; } kParams.dmux = WebPDemux(&kParams.data); if (kParams.dmux == NULL) { fprintf(stderr, "Could not create demuxing object!\n"); goto Error; } if (WebPDemuxGetI(kParams.dmux, WEBP_FF_FORMAT_FLAGS) & FRAGMENTS_FLAG) { fprintf(stderr, "Image fragments are not supported for now!\n"); goto Error; } kParams.canvas_width = WebPDemuxGetI(kParams.dmux, WEBP_FF_CANVAS_WIDTH); kParams.canvas_height = WebPDemuxGetI(kParams.dmux, WEBP_FF_CANVAS_HEIGHT); if (kParams.print_info) { printf("Canvas: %d x %d\n", kParams.canvas_width, kParams.canvas_height); } prev->width = kParams.canvas_width; prev->height = kParams.canvas_height; prev->x_offset = prev->y_offset = 0; prev->dispose_method = WEBP_MUX_DISPOSE_BACKGROUND; memset(&kParams.iccp, 0, sizeof(kParams.iccp)); kParams.has_color_profile = !!(WebPDemuxGetI(kParams.dmux, WEBP_FF_FORMAT_FLAGS) & ICCP_FLAG); if (kParams.has_color_profile) { #ifdef WEBP_HAVE_QCMS if (!WebPDemuxGetChunk(kParams.dmux, "ICCP", 1, &kParams.iccp)) goto Error; printf("VP8X: Found color profile\n"); #else fprintf(stderr, "Warning: color profile present, but qcms is unavailable!\n" "Build libqcms from Mozilla or Chromium and define WEBP_HAVE_QCMS " "before building.\n"); #endif } if (!WebPDemuxGetFrame(kParams.dmux, 1, curr)) goto Error; kParams.has_animation = (curr->num_frames > 1); kParams.loop_count = (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT); kParams.bg_color = WebPDemuxGetI(kParams.dmux, WEBP_FF_BACKGROUND_COLOR); printf("VP8X: Found %d images in file (loop count = %d)\n", curr->num_frames, kParams.loop_count); // Decode first frame if (!Decode()) goto Error; // Position iterator to last frame. Next call to HandleDisplay will wrap over. // We take this into account by bumping up loop_count. WebPDemuxGetFrame(kParams.dmux, 0, curr); if (kParams.loop_count) ++kParams.loop_count; // Start display (and timer) glutInit(&argc, argv); #ifdef FREEGLUT glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); #endif StartDisplay(); if (kParams.has_animation) glutTimerFunc(0, decode_callback, 0); glutMainLoop(); // Should only be reached when using FREEGLUT: ClearParams(); return 0; Error: ClearParams(); return -1; } #else // !WEBP_HAVE_GL int main(int argc, const char *argv[]) { fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]); (void)argc; return 0; } #endif //------------------------------------------------------------------------------ libwebp-0.4.0/examples/test.webp0000644000014400001440000001142012255002107013513 0ustar RIFFWEBPVP8 üÐ>*€€……ˆ…„ˆ‚ÁÓ/'Ug*Ngñ7ÿÝŒý¾9ýúŸçSn ü+ó/Á×­}ÏõsÉ_YZ…ü³íçê?¼þãüeþ¼ÿ’:‚ûý_оÃm£ýoüïP^ðÅÿâÛþç ß[¿ç{€ÿ2þaþÛÕOó~uÿKìýûgýoóߘß$Ÿñ™üÞöïôÏþOó_ÿ«?òÿ¼{^ÿÿ÷=û…ì±úÇÿ‡ÞüÖáÌ·Å"ó$úÑ—w/­ÿ2 Šn<•BWª}7Òãßæ’¢$B˜ …áÒÔEIþK‡¹¯§åa‹šl¹6Ï•ò&/„V/M:žÈ'çî½×½•í–7È>™´æ1ØhŽÜŸm®•xœøŠ˜š0ÎK=»ø†qF YAbÖ‡uäŽ×"[ËÈ1‰Ðª¿2¾+²!‘Ou¢þ†f"$cnËÚ.½Ñ½y s‘/"UºJž?.\«6…löÿ-ŽÂ0º©”çÿFt“úD0aC˜Ìæ `â9ÜmÌNn!믂&—¶sßwfäëD›hpË2Í1a ÿÿ,µ«uZÀ§(×ψ'”Å õ¼„ˆpN4o°LBj]î~Pù¶Ê:MX¿uß=ÕëC¥í¥÷f¸s=æ{!Øô]pz»¹ þÿþõt|Ÿÿ’ùçý^i£ÿɼ/î,i ¤pO~ñ¿>¬Üè#4@íFuñs¡ÁÄð? ¥TýTôÛÓ(äQ9:Xivo‚üÒµ‘Tž â;ô%ÄÇ¡ü®-ÿ°NË,€v'LŸôV#?eâö«êvoÖó ØYmÞIóiUº…;€·Ý}-·Fb0–{€572…¸F0ïJMˆ6uùp¦b£uap‹k}9,•ŸÊØŠ[êSÆŸÂ9ãœð¥Òe‹ugÑ/^­¶fO+XW<·ˆaøµNf¿Ößûè–v{þa“—ùD/¿î,»žéM!Y`uL  Ù"Á‘ª”•5×âj[è*Ý\ر¸§ô>8Q­¿µÿzé=4t͈Šî—uå ·Ðú2{=¼/wï ÑWéÅÓ*\G©u1ÿÁµ[cè%½Mï–Ïr6?þüD5}ÌbƒôÓóÃ*Üþs;•Ú[={¹ÿ¦eqÓVÿñ PåÚZûý¹X–â²åªÒŸAxzUÀh¦.ürç ×òú¢þ¯FæOÖQM4î êÀ'üWŒXÐ-Ì«ôjj²²ê¶½ã؂ꗊm€0Jz‹îUegßIDw€5&ôÒSÄìèüÈïÛo”oÿž˜y\‘òm¢ÝþìéÊEƒ-B±~^,Êã.u‡ˆÞšÛ÷_³WJÙð[¿†$Þ_ø€¡Â“ÁĹC6k â_À~»#Ô’ ˆ°9C4e v¨•\]µÿVù¦³t?ÓŸñ5àˆ¦Ñ ¯)9reÈÈúj^–JÉÉhMD‰¤%XqoËzxcBÏŒB°t¨2,í£ÈòiÑF¶@Q!)JœI±"†híwg÷,¥¤µè¹À’w­¬SSªßVØXÒ@Ë‘ïË7æŽ;h}ÇMäÙýô CX9È}™qïó¬ñÑ\G}„ãà1±tñnM„¡/éÙç¬Ó%m(³.uAÊ%f>ÚaÙ  !AÁmž*š˜òÜgvÛ/-ür¹zQBÜ4{Hâ:épcéé‡õT:øÏ)ƒÂÍém.ôoìZ’¹æÐ61à qCr)›sÖøs;Æþû1“M¿oo( ðZC6EfÆ«ùO– ^|Õô{iø‘Àì¹§`s ¢`ý*œ­4q ¢øYˆ:àæô?殄°â=Ø Wõ 念Úo*e q&{})%îZÓ‡¢»ÄAD?fÚ@‰‘¢<ñ=ùf8T0ÅDö,ð»N ¨Æcç†FˆÜu ]ï¢ru«ÊtMKžã%ó:«–—B…~ÅFPðGYƒùNklÂ}à¥*œØùI’[xD„gT™ºÛø¹O1º\Â&h æVbh¦^=GÚ™˜“> •d,C ø Ï×°üDñôÏ}Fï®xleŠ‚JñBõFEV’¢–¸ÜÂŒWÄ®ÈZôßæ€tœ0eÎ.è§ò±åûíKvµëò%ì‡zqæâ\KKr°h¦ŽOÏ^îl‡›"ÄÜè"&>³h§j›Œ­À‡ŒHÕ‘áF“ÞNü+B5Ï_TÁ‘ãžÆl+Y¤³kJ8–`×ò kŒPFŒö«qï|[µýøU«›è9ÁÔp^êbÿ¼›A¶³û]š1oª1ú‘ëçþ뼿Š–7!–yL¤zŸ6¬Ïɘϒsü>Î[8”MÒv°Ä\,—·I·E¸GRÌ¡ùøìþA?TUøgEö×ð4:yQROMôÌ[“¿ öPÔ<j]ÖÜ·Wa×`1Pý­ÍÁÇèLdW¸ FˆÀTº¯°¬y¡—(ôsÔ¦IŒÉ@©˜[‘÷1÷–wó˜/a_]‹q £ÎÇWG|yó›©*Wwî— û ™Øˆ‹Yy¯üTñ°‰¢Ùÿ™æ±”Šz+úwœ×î×7É "¨3× ^­Z–%xepÍ}NƒOmnõÁm߈¾B~´ð˜S!u÷ú˜XÅÃç\Õî‡3Û80oÿiüÝ?Áª«½eòû®-,ÍRÈPükV8€ã]¨ÖÍ“{&6™Ã¹t«tŽ«‰"³G…1´;JPZøÂÞ*/f š^7®ú϶¯¥Ù¨Ç o·a—&»ó2ŽÐVïœ$®‡Tà£ô-#Òÿn…f¶ÙìßL'$yY;š+eìÿ¨<¾Öp†zî]€muÍkÔù»GäDz$9aŸ.ß‘62a}ó¯Qü‚E_¦9˜>S2äO›»f¯ìaÜ!ËÚT¼èOÑÿUøE©:Æ"´QØF^~}‰<5eµÝäŸæÌéO^Û>ôAìŠó_¦–yŸþéF/<×î¹¾ƒÄÊ.¾ÊŠB¸ÍV'öâZ8u©á'„âYÁ„OK{:X!GÌèÃ%SÂ[uËrwXþódËhs0`šÈê»g´&Á´4d±WŽyÀšL]—=\H4ä$^Çxð^T#:›4¡¶ú‘aÀSôWÆz#WŽÓ´[c¾d3þQDNâ×düU¯(‘Šª‡ü/’mÊvÞdQ(z¿Å³~Ùq Í¼5öÓŸ‚ô—§ÉÅëçWà‚”ço"Ï;àØ5Ê`ã;-ïz±Ôv Êiª»Í˜h½çHÃÔÇO-›ÀN7övæ{ûnûll¿A'ì0· ŸH3ÞÀŒ7$ªüìŠ s¾§ý1ú|õ ?©œŠ#ïù-LÚ9]°&“ÓuÕvÝ)®R€´TSz[` «7Ò–Äw9Ž8ü²°4ýaqtçQW×å±L8%À ¸j%±h“]Ò¬EY®e$z˜sg“¹ûíTÓË¿!]•⺠ló‹|ÑRðKÓ›Ýh§ÊcrÏ3ñÈ«TM—À5”²óß›t¸‰ðpÌËÏ},æ: kë(xW·NTï•°òÇϱà0«N9ûІkàßä¿k¤ÖžXA7ÜçÐ*ä‘㕞‰p3cŸVq)´Îc( ûQ…ºÖeO‚<ÔçAnÀ1Ý2h]°(gx'Ó ‰qæÏšþÓ‘ðÃk.¤ù™+¥‚Ì}"UCf7þ1Eäʽ°Q2 Õ,Å€_Ü®¶YÙà5ôœžWކ?‡ ¸$Auü|u~°1Ž ÏöM¸ê™Ø·ÿ庖£ÿ”1.ÐÒeIÖáã²až Äµ)±š›¨'@Ó„7­ÑÖ»¤ÅwOSŸ 4>©x`Ëè”ÐÉfñ‰=.‘¿"s z›‡hÇ«ífl¼C?_;^»¢ðî º TÝC{ÔÊIr_æûö ¬H)±XÔÀ:IR¢"o7ŽP §bP!&399)LìÉ…dРõž%¤Dó[ϾàBÄ1`E4´*ã› 3zBÄÈöYZfúGÖ˜üúŒ¦Jµž)§WÛZõþ—OÊ_Öv¡ÑŽG部B«´Ó¢Cf™<ìy DHǹŒØ¿>²¼€ìXÆí€ÄÇ›‰ø>¾d1†NÀ‘FCg£·@g€_`€7¹M@1âÎ0ê’ëíCÛg¾RŸ”³ú±>1UGˆü™m®+PͲÎî`¯Öä†0iËr)š¼¥3GºÀŒ*`½Ç‘j̨jõà €ãP˜¬™SZ$èÉ®›ãeÆBg|ñx—øR¨ò@_Ÿv"ºì„¹b(^eP;Ú;ÐåÖtî6µLž¬’çïj|ŽÐ4"<ÕZ¸+ªF|BýyT€2ÙéÀ$z&6@Fðž†Ëž$´~îI昰s3Ç"qZ[:ÎùÓ«NnŸ2À»V<1ÁÙ÷iF#»hÁ„±¿Û²ýäU-©0ý z$}Á!ˆG %Ž¥ïFîÔ¥¿7¢tC*áÊ Tþ´<©ÔžÂ_0 ÓÌKÆQ&_|/´öA³`§qôë<ºH óű²Œ>Yüo Äo>&CslÞ)?¶ZϹ­T¾ªÕ´²ïGÎÅÈØê†FæË>:jáö84G"‡@ÐÁ.´† Z–+ËtÖ,fí⢬^„^¶¢;örk~ÊŒY—ä<‘ û¢…ý ÑåF#¡´v‘Ã]YÚHê’ž¨šHÊ=%†ÏJ„s,P©KHŸœl2¾8N ËÔp±Ñ˜¡®É+q3UyH“*”¶TĨmÌó}ä¾=jnuª(Š<b|¹BÍèþ'§^†¹F¦¬F ì ý*#Ú‡0±£ÔV_ü‚²? C 7‘' Dhî»i’€tè4ïZº³ÃçÞélibwebp-0.4.0/examples/example_util.c0000644000014400001440000000364312255002107014521 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utility functions used by the example programs. // #include "./example_util.h" #include #include // ----------------------------------------------------------------------------- // File I/O int ExUtilReadFile(const char* const file_name, const uint8_t** data, size_t* data_size) { int ok; void* file_data; size_t file_size; FILE* in; if (file_name == NULL || data == NULL || data_size == NULL) return 0; *data = NULL; *data_size = 0; in = fopen(file_name, "rb"); if (in == NULL) { fprintf(stderr, "cannot open input file '%s'\n", file_name); return 0; } fseek(in, 0, SEEK_END); file_size = ftell(in); fseek(in, 0, SEEK_SET); file_data = malloc(file_size); if (file_data == NULL) return 0; ok = (fread(file_data, file_size, 1, in) == 1); fclose(in); if (!ok) { fprintf(stderr, "Could not read %d bytes of data from file %s\n", (int)file_size, file_name); free(file_data); return 0; } *data = (uint8_t*)file_data; *data_size = file_size; return 1; } int ExUtilWriteFile(const char* const file_name, const uint8_t* data, size_t data_size) { int ok; FILE* out; if (file_name == NULL || data == NULL) { return 0; } out = fopen(file_name, "wb"); if (out == NULL) { fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name); return 0; } ok = (fwrite(data, data_size, 1, out) == 1); fclose(out); return ok; } libwebp-0.4.0/examples/cwebp.c0000644000014400001440000011762312255002107013135 0ustar // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // simple command line calling the WebPEncode function. // Encodes a raw .YUV into WebP bitstream // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "webp/encode.h" #include "./metadata.h" #include "./stopwatch.h" #include "./jpegdec.h" #include "./pngdec.h" #include "./tiffdec.h" #include "./wicdec.h" #ifndef WEBP_DLL #ifdef __cplusplus extern "C" { #endif extern void* VP8GetCPUInfo; // opaque forward declaration. #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_DLL //------------------------------------------------------------------------------ static int verbose = 0; static int ReadYUV(FILE* in_file, WebPPicture* const pic) { const int use_argb = pic->use_argb; const int uv_width = (pic->width + 1) / 2; const int uv_height = (pic->height + 1) / 2; int y; int ok = 0; pic->use_argb = 0; if (!WebPPictureAlloc(pic)) return ok; for (y = 0; y < pic->height; ++y) { if (fread(pic->y + y * pic->y_stride, pic->width, 1, in_file) != 1) { goto End; } } for (y = 0; y < uv_height; ++y) { if (fread(pic->u + y * pic->uv_stride, uv_width, 1, in_file) != 1) goto End; } for (y = 0; y < uv_height; ++y) { if (fread(pic->v + y * pic->uv_stride, uv_width, 1, in_file) != 1) goto End; } ok = 1; if (use_argb) ok = WebPPictureYUVAToARGB(pic); End: return ok; } #ifdef HAVE_WINCODEC_H static int ReadPicture(const char* const filename, WebPPicture* const pic, int keep_alpha, Metadata* const metadata) { int ok; if (pic->width != 0 && pic->height != 0) { // If image size is specified, infer it as YUV format. FILE* in_file = fopen(filename, "rb"); if (in_file == NULL) { fprintf(stderr, "Error! Cannot open input file '%s'\n", filename); return 0; } ok = ReadYUV(in_file, pic); fclose(in_file); } else { // If no size specified, try to decode it using WIC. ok = ReadPictureWithWIC(filename, pic, keep_alpha, metadata); } if (!ok) { fprintf(stderr, "Error! Could not process file %s\n", filename); } return ok; } #else // !HAVE_WINCODEC_H typedef enum { PNG_ = 0, JPEG_, TIFF_, // 'TIFF' clashes with libtiff UNSUPPORTED } InputFileFormat; static InputFileFormat GetImageType(FILE* in_file) { InputFileFormat format = UNSUPPORTED; uint32_t magic; uint8_t buf[4]; if ((fread(&buf[0], 4, 1, in_file) != 1) || (fseek(in_file, 0, SEEK_SET) != 0)) { return format; } magic = ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; if (magic == 0x89504E47U) { format = PNG_; } else if (magic >= 0xFFD8FF00U && magic <= 0xFFD8FFFFU) { format = JPEG_; } else if (magic == 0x49492A00 || magic == 0x4D4D002A) { format = TIFF_; } return format; } static int ReadPicture(const char* const filename, WebPPicture* const pic, int keep_alpha, Metadata* const metadata) { int ok = 0; FILE* in_file = fopen(filename, "rb"); if (in_file == NULL) { fprintf(stderr, "Error! Cannot open input file '%s'\n", filename); return ok; } if (pic->width == 0 || pic->height == 0) { // If no size specified, try to decode it as PNG/JPEG (as appropriate). const InputFileFormat format = GetImageType(in_file); if (format == PNG_) { ok = ReadPNG(in_file, pic, keep_alpha, metadata); } else if (format == JPEG_) { ok = ReadJPEG(in_file, pic, metadata); } else if (format == TIFF_) { ok = ReadTIFF(filename, pic, keep_alpha, metadata); } } else { // If image size is specified, infer it as YUV format. ok = ReadYUV(in_file, pic); } if (!ok) { fprintf(stderr, "Error! Could not process file %s\n", filename); } fclose(in_file); return ok; } #endif // !HAVE_WINCODEC_H static void AllocExtraInfo(WebPPicture* const pic) { const int mb_w = (pic->width + 15) / 16; const int mb_h = (pic->height + 15) / 16; pic->extra_info = (uint8_t*)malloc(mb_w * mb_h * sizeof(*pic->extra_info)); } static void PrintByteCount(const int bytes[4], int total_size, int* const totals) { int s; int total = 0; for (s = 0; s < 4; ++s) { fprintf(stderr, "| %7d ", bytes[s]); total += bytes[s]; if (totals) totals[s] += bytes[s]; } fprintf(stderr, "| %7d (%.1f%%)\n", total, 100.f * total / total_size); } static void PrintPercents(const int counts[4], int total) { int s; for (s = 0; s < 4; ++s) { fprintf(stderr, "| %2d%%", 100 * counts[s] / total); } fprintf(stderr, "| %7d\n", total); } static void PrintValues(const int values[4]) { int s; for (s = 0; s < 4; ++s) { fprintf(stderr, "| %7d ", values[s]); } fprintf(stderr, "|\n"); } static void PrintFullLosslessInfo(const WebPAuxStats* const stats, const char* const description) { fprintf(stderr, "Lossless-%s compressed size: %d bytes\n", description, stats->lossless_size); if (stats->lossless_features) { fprintf(stderr, " * Lossless features used:"); if (stats->lossless_features & 1) fprintf(stderr, " PREDICTION"); if (stats->lossless_features & 2) fprintf(stderr, " CROSS-COLOR-TRANSFORM"); if (stats->lossless_features & 4) fprintf(stderr, " SUBTRACT-GREEN"); if (stats->lossless_features & 8) fprintf(stderr, " PALETTE"); fprintf(stderr, "\n"); } fprintf(stderr, " * Precision Bits: histogram=%d transform=%d cache=%d\n", stats->histogram_bits, stats->transform_bits, stats->cache_bits); if (stats->palette_size > 0) { fprintf(stderr, " * Palette size: %d\n", stats->palette_size); } } static void PrintExtraInfoLossless(const WebPPicture* const pic, int short_output, const char* const file_name) { const WebPAuxStats* const stats = pic->stats; if (short_output) { fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]); } else { fprintf(stderr, "File: %s\n", file_name); fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height); fprintf(stderr, "Output: %d bytes\n", stats->coded_size); PrintFullLosslessInfo(stats, "ARGB"); } } static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output, int full_details, const char* const file_name) { const WebPAuxStats* const stats = pic->stats; if (short_output) { fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]); } else { const int num_i4 = stats->block_count[0]; const int num_i16 = stats->block_count[1]; const int num_skip = stats->block_count[2]; const int total = num_i4 + num_i16; fprintf(stderr, "File: %s\n", file_name); fprintf(stderr, "Dimension: %d x %d%s\n", pic->width, pic->height, stats->alpha_data_size ? " (with alpha)" : ""); fprintf(stderr, "Output: " "%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n", stats->coded_size, stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3]); if (total > 0) { int totals[4] = { 0, 0, 0, 0 }; fprintf(stderr, "block count: intra4: %d\n" " intra16: %d (-> %.2f%%)\n", num_i4, num_i16, 100.f * num_i16 / total); fprintf(stderr, " skipped block: %d (%.2f%%)\n", num_skip, 100.f * num_skip / total); fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n" " mode-partition: %6d (%.1f%%)\n", stats->header_bytes[0], 100.f * stats->header_bytes[0] / stats->coded_size, stats->header_bytes[1], 100.f * stats->header_bytes[1] / stats->coded_size); if (stats->alpha_data_size > 0) { fprintf(stderr, " transparency: %6d (%.1f dB)\n", stats->alpha_data_size, stats->PSNR[4]); } if (stats->layer_data_size) { fprintf(stderr, " enhancement: %6d\n", stats->layer_data_size); } fprintf(stderr, " Residuals bytes " "|segment 1|segment 2|segment 3" "|segment 4| total\n"); if (full_details) { fprintf(stderr, " intra4-coeffs: "); PrintByteCount(stats->residual_bytes[0], stats->coded_size, totals); fprintf(stderr, " intra16-coeffs: "); PrintByteCount(stats->residual_bytes[1], stats->coded_size, totals); fprintf(stderr, " chroma coeffs: "); PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals); } fprintf(stderr, " macroblocks: "); PrintPercents(stats->segment_size, total); fprintf(stderr, " quantizer: "); PrintValues(stats->segment_quant); fprintf(stderr, " filter level: "); PrintValues(stats->segment_level); if (full_details) { fprintf(stderr, "------------------+---------"); fprintf(stderr, "+---------+---------+---------+-----------------\n"); fprintf(stderr, " segments total: "); PrintByteCount(totals, stats->coded_size, NULL); } } if (stats->lossless_size > 0) { PrintFullLosslessInfo(stats, "alpha"); } } if (pic->extra_info != NULL) { const int mb_w = (pic->width + 15) / 16; const int mb_h = (pic->height + 15) / 16; const int type = pic->extra_info_type; int x, y; for (y = 0; y < mb_h; ++y) { for (x = 0; x < mb_w; ++x) { const int c = pic->extra_info[x + y * mb_w]; if (type == 1) { // intra4/intra16 printf("%c", "+."[c]); } else if (type == 2) { // segments printf("%c", ".-*X"[c]); } else if (type == 3) { // quantizers printf("%.2d ", c); } else if (type == 6 || type == 7) { printf("%3d ", c); } else { printf("0x%.2x ", c); } } printf("\n"); } } } //------------------------------------------------------------------------------ static int MyWriter(const uint8_t* data, size_t data_size, const WebPPicture* const pic) { FILE* const out = (FILE*)pic->custom_ptr; return data_size ? (fwrite(data, data_size, 1, out) == 1) : 1; } // Dumps a picture as a PGM file using the IMC4 layout. static int DumpPicture(const WebPPicture* const picture, const char* PGM_name) { int y; const int uv_width = (picture->width + 1) / 2; const int uv_height = (picture->height + 1) / 2; const int stride = (picture->width + 1) & ~1; const int alpha_height = WebPPictureHasTransparency(picture) ? picture->height : 0; const int height = picture->height + uv_height + alpha_height; FILE* const f = fopen(PGM_name, "wb"); if (f == NULL) return 0; fprintf(f, "P5\n%d %d\n255\n", stride, height); for (y = 0; y < picture->height; ++y) { if (fwrite(picture->y + y * picture->y_stride, picture->width, 1, f) != 1) return 0; if (picture->width & 1) fputc(0, f); // pad } for (y = 0; y < uv_height; ++y) { if (fwrite(picture->u + y * picture->uv_stride, uv_width, 1, f) != 1) return 0; if (fwrite(picture->v + y * picture->uv_stride, uv_width, 1, f) != 1) return 0; } for (y = 0; y < alpha_height; ++y) { if (fwrite(picture->a + y * picture->a_stride, picture->width, 1, f) != 1) return 0; if (picture->width & 1) fputc(0, f); // pad } fclose(f); return 1; } // ----------------------------------------------------------------------------- // Metadata writing. enum { METADATA_EXIF = (1 << 0), METADATA_ICC = (1 << 1), METADATA_XMP = (1 << 2), METADATA_ALL = METADATA_EXIF | METADATA_ICC | METADATA_XMP }; static const int kChunkHeaderSize = 8; static const int kTagSize = 4; static void PrintMetadataInfo(const Metadata* const metadata, int metadata_written) { if (metadata == NULL || metadata_written == 0) return; fprintf(stderr, "Metadata:\n"); if (metadata_written & METADATA_ICC) { fprintf(stderr, " * ICC profile: %6d bytes\n", (int)metadata->iccp.size); } if (metadata_written & METADATA_EXIF) { fprintf(stderr, " * EXIF data: %6d bytes\n", (int)metadata->exif.size); } if (metadata_written & METADATA_XMP) { fprintf(stderr, " * XMP data: %6d bytes\n", (int)metadata->xmp.size); } } // Outputs, in little endian, 'num' bytes from 'val' to 'out'. static int WriteLE(FILE* const out, uint32_t val, int num) { uint8_t buf[4]; int i; for (i = 0; i < num; ++i) { buf[i] = (uint8_t)(val & 0xff); val >>= 8; } return (fwrite(buf, num, 1, out) == 1); } static int WriteLE24(FILE* const out, uint32_t val) { return WriteLE(out, val, 3); } static int WriteLE32(FILE* const out, uint32_t val) { return WriteLE(out, val, 4); } static int WriteMetadataChunk(FILE* const out, const char fourcc[4], const MetadataPayload* const payload) { const uint8_t zero = 0; const size_t need_padding = payload->size & 1; int ok = (fwrite(fourcc, kTagSize, 1, out) == 1); ok = ok && WriteLE32(out, (uint32_t)payload->size); ok = ok && (fwrite(payload->bytes, payload->size, 1, out) == 1); return ok && (fwrite(&zero, need_padding, need_padding, out) == need_padding); } // Sets 'flag' in 'vp8x_flags' and updates 'metadata_size' with the size of the // chunk if there is metadata and 'keep' is true. static int UpdateFlagsAndSize(const MetadataPayload* const payload, int keep, int flag, uint32_t* vp8x_flags, uint64_t* metadata_size) { if (keep && payload->bytes != NULL && payload->size > 0) { *vp8x_flags |= flag; *metadata_size += kChunkHeaderSize + payload->size + (payload->size & 1); return 1; } return 0; } // Writes a WebP file using the image contained in 'memory_writer' and the // metadata from 'metadata'. Metadata is controlled by 'keep_metadata' and the // availability in 'metadata'. Returns true on success. // For details see doc/webp-container-spec.txt#extended-file-format. static int WriteWebPWithMetadata(FILE* const out, const WebPPicture* const picture, const WebPMemoryWriter* const memory_writer, const Metadata* const metadata, int keep_metadata, int* const metadata_written) { const char kVP8XHeader[] = "VP8X\x0a\x00\x00\x00"; const int kAlphaFlag = 0x10; const int kEXIFFlag = 0x08; const int kICCPFlag = 0x20; const int kXMPFlag = 0x04; const size_t kRiffHeaderSize = 12; const size_t kMaxChunkPayload = ~0 - kChunkHeaderSize - 1; const size_t kMinSize = kRiffHeaderSize + kChunkHeaderSize; uint32_t flags = 0; uint64_t metadata_size = 0; const int write_exif = UpdateFlagsAndSize(&metadata->exif, !!(keep_metadata & METADATA_EXIF), kEXIFFlag, &flags, &metadata_size); const int write_iccp = UpdateFlagsAndSize(&metadata->iccp, !!(keep_metadata & METADATA_ICC), kICCPFlag, &flags, &metadata_size); const int write_xmp = UpdateFlagsAndSize(&metadata->xmp, !!(keep_metadata & METADATA_XMP), kXMPFlag, &flags, &metadata_size); uint8_t* webp = memory_writer->mem; size_t webp_size = memory_writer->size; *metadata_written = 0; if (webp_size < kMinSize) return 0; if (webp_size - kChunkHeaderSize + metadata_size > kMaxChunkPayload) { fprintf(stderr, "Error! Addition of metadata would exceed " "container size limit.\n"); return 0; } if (metadata_size > 0) { const int kVP8XChunkSize = 18; const int has_vp8x = !memcmp(webp + kRiffHeaderSize, "VP8X", kTagSize); const uint32_t riff_size = (uint32_t)(webp_size - kChunkHeaderSize + (has_vp8x ? 0 : kVP8XChunkSize) + metadata_size); // RIFF int ok = (fwrite(webp, kTagSize, 1, out) == 1); // RIFF size (file header size is not recorded) ok = ok && WriteLE32(out, riff_size); webp += kChunkHeaderSize; webp_size -= kChunkHeaderSize; // WEBP ok = ok && (fwrite(webp, kTagSize, 1, out) == 1); webp += kTagSize; webp_size -= kTagSize; if (has_vp8x) { // update the existing VP8X flags webp[kChunkHeaderSize] |= (uint8_t)(flags & 0xff); ok = ok && (fwrite(webp, kVP8XChunkSize, 1, out) == 1); webp += kVP8XChunkSize; webp_size -= kVP8XChunkSize; } else { const int is_lossless = !memcmp(webp, "VP8L", kTagSize); if (is_lossless) { // Presence of alpha is stored in the 29th bit of VP8L data. if (webp[kChunkHeaderSize + 3] & (1 << 5)) flags |= kAlphaFlag; } ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1); ok = ok && WriteLE32(out, flags); ok = ok && WriteLE24(out, picture->width - 1); ok = ok && WriteLE24(out, picture->height - 1); } if (write_iccp) { ok = ok && WriteMetadataChunk(out, "ICCP", &metadata->iccp); *metadata_written |= METADATA_ICC; } // Image ok = ok && (fwrite(webp, webp_size, 1, out) == 1); if (write_exif) { ok = ok && WriteMetadataChunk(out, "EXIF", &metadata->exif); *metadata_written |= METADATA_EXIF; } if (write_xmp) { ok = ok && WriteMetadataChunk(out, "XMP ", &metadata->xmp); *metadata_written |= METADATA_XMP; } return ok; } else { // No metadata, just write the original image file. return (fwrite(webp, webp_size, 1, out) == 1); } } //------------------------------------------------------------------------------ static int ProgressReport(int percent, const WebPPicture* const picture) { printf("[%s]: %3d %% \r", (char*)picture->user_data, percent); fflush(stdout); return 1; // all ok } //------------------------------------------------------------------------------ static void HelpShort(void) { printf("Usage:\n\n"); printf(" cwebp [options] -q quality input.png -o output.webp\n\n"); printf("where quality is between 0 (poor) to 100 (very good).\n"); printf("Typical value is around 80.\n\n"); printf("Try -longhelp for an exhaustive list of advanced options.\n"); } static void HelpLong(void) { printf("Usage:\n"); printf(" cwebp [-preset <...>] [options] in_file [-o out_file]\n\n"); printf("If input size (-s) for an image is not specified, " "it is assumed to be a PNG, JPEG or TIFF file.\n"); #ifdef HAVE_WINCODEC_H printf("Windows builds can take as input any of the files handled by WIC\n"); #endif printf("options:\n"); printf(" -h / -help ............ short help\n"); printf(" -H / -longhelp ........ long help\n"); printf(" -q ............. quality factor (0:small..100:big)\n"); printf(" -alpha_q ......... Transparency-compression quality " "(0..100).\n"); printf(" -preset ....... Preset setting, one of:\n"); printf(" default, photo, picture,\n"); printf(" drawing, icon, text\n"); printf(" -preset must come first, as it overwrites other parameters."); printf("\n"); printf(" -m ............... compression method (0=fast, 6=slowest)\n"); printf(" -segments ........ number of segments to use (1..4)\n"); printf(" -size ............ Target size (in bytes)\n"); printf(" -psnr .......... Target PSNR (in dB. typically: 42)\n"); printf("\n"); printf(" -s ......... Input size (width x height) for YUV\n"); printf(" -sns ............. Spatial Noise Shaping (0:off, 100:max)\n"); printf(" -f ............... filter strength (0=off..100)\n"); printf(" -sharpness ....... " "filter sharpness (0:most .. 7:least sharp)\n"); printf(" -strong ................ use strong filter instead " "of simple (default).\n"); printf(" -nostrong .............. use simple filter instead of strong.\n"); printf(" -partition_limit . limit quality to fit the 512k limit on\n"); printf(" " "the first partition (0=no degradation ... 100=full)\n"); printf(" -pass ............ analysis pass number (1..10)\n"); printf(" -crop .. crop picture with the given rectangle\n"); printf(" -resize ........ resize picture (after any cropping)\n"); printf(" -mt .................... use multi-threading if available\n"); printf(" -low_memory ............ reduce memory usage (slower encoding)\n"); #ifdef WEBP_EXPERIMENTAL_FEATURES printf(" -444 / -422 / -gray ..... Change colorspace\n"); #endif printf(" -map ............. print map of extra info.\n"); printf(" -print_psnr ............ prints averaged PSNR distortion.\n"); printf(" -print_ssim ............ prints averaged SSIM distortion.\n"); printf(" -print_lsim ............ prints local-similarity distortion.\n"); printf(" -d .......... dump the compressed output (PGM file).\n"); printf(" -alpha_method .... Transparency-compression method (0..1)\n"); printf(" -alpha_filter . predictive filtering for alpha plane.\n"); printf(" One of: none, fast (default) or best.\n"); printf(" -alpha_cleanup ......... Clean RGB values in transparent area.\n"); printf(" -blend_alpha ..... Blend colors against background color\n" " expressed as RGB values written in\n" " hexadecimal, e.g. 0xc0e0d0 for red=0xc0\n" " green=0xe0 and blue=0xd0.\n"); printf(" -noalpha ............... discard any transparency information.\n"); printf(" -lossless .............. Encode image losslessly.\n"); printf(" -hint ......... Specify image characteristics hint.\n"); printf(" One of: photo, picture or graph\n"); printf("\n"); printf(" -metadata ..... comma separated list of metadata to\n"); printf(" "); printf("copy from the input to the output if present.\n"); printf(" " "Valid values: all, none (default), exif, icc, xmp\n"); printf("\n"); printf(" -short ................. condense printed message\n"); printf(" -quiet ................. don't print anything.\n"); printf(" -version ............... print version number and exit.\n"); #ifndef WEBP_DLL printf(" -noasm ................. disable all assembly optimizations.\n"); #endif printf(" -v ..................... verbose, e.g. print encoding/decoding " "times\n"); printf(" -progress .............. report encoding progress\n"); printf("\n"); printf("Experimental Options:\n"); printf(" -jpeg_like ............. Roughly match expected JPEG size.\n"); printf(" -af .................... auto-adjust filter strength.\n"); printf(" -pre ............. pre-processing filter\n"); printf("\n"); } //------------------------------------------------------------------------------ // Error messages static const char* const kErrorMessages[] = { "OK", "OUT_OF_MEMORY: Out of memory allocating objects", "BITSTREAM_OUT_OF_MEMORY: Out of memory re-allocating byte buffer", "NULL_PARAMETER: NULL parameter passed to function", "INVALID_CONFIGURATION: configuration is invalid", "BAD_DIMENSION: Bad picture dimension. Maximum width and height " "allowed is 16383 pixels.", "PARTITION0_OVERFLOW: Partition #0 is too big to fit 512k.\n" "To reduce the size of this partition, try using less segments " "with the -segments option, and eventually reduce the number of " "header bits using -partition_limit. More details are available " "in the manual (`man cwebp`)", "PARTITION_OVERFLOW: Partition is too big to fit 16M", "BAD_WRITE: Picture writer returned an I/O error", "FILE_TOO_BIG: File would be too big to fit in 4G", "USER_ABORT: encoding abort requested by user" }; //------------------------------------------------------------------------------ int main(int argc, const char *argv[]) { int return_value = -1; const char *in_file = NULL, *out_file = NULL, *dump_file = NULL; FILE *out = NULL; int c; int short_output = 0; int quiet = 0; int keep_alpha = 1; int blend_alpha = 0; uint32_t background_color = 0xffffffu; int crop = 0, crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0; int resize_w = 0, resize_h = 0; int show_progress = 0; int keep_metadata = 0; int metadata_written = 0; WebPPicture picture; int print_distortion = -1; // -1=off, 0=PSNR, 1=SSIM, 2=LSIM WebPPicture original_picture; // when PSNR or SSIM is requested WebPConfig config; WebPAuxStats stats; WebPMemoryWriter memory_writer; Metadata metadata; Stopwatch stop_watch; MetadataInit(&metadata); WebPMemoryWriterInit(&memory_writer); if (!WebPPictureInit(&picture) || !WebPPictureInit(&original_picture) || !WebPConfigInit(&config)) { fprintf(stderr, "Error! Version mismatch!\n"); return -1; } if (argc == 1) { HelpShort(); return 0; } for (c = 1; c < argc; ++c) { if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { HelpShort(); return 0; } else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) { HelpLong(); return 0; } else if (!strcmp(argv[c], "-o") && c < argc - 1) { out_file = argv[++c]; } else if (!strcmp(argv[c], "-d") && c < argc - 1) { dump_file = argv[++c]; config.show_compressed = 1; } else if (!strcmp(argv[c], "-print_psnr")) { config.show_compressed = 1; print_distortion = 0; } else if (!strcmp(argv[c], "-print_ssim")) { config.show_compressed = 1; print_distortion = 1; } else if (!strcmp(argv[c], "-print_lsim")) { config.show_compressed = 1; print_distortion = 2; } else if (!strcmp(argv[c], "-short")) { short_output++; } else if (!strcmp(argv[c], "-s") && c < argc - 2) { picture.width = strtol(argv[++c], NULL, 0); picture.height = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-m") && c < argc - 1) { config.method = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-q") && c < argc - 1) { config.quality = (float)strtod(argv[++c], NULL); } else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) { config.alpha_quality = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) { config.alpha_compression = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-alpha_cleanup")) { keep_alpha = keep_alpha ? 2 : 0; } else if (!strcmp(argv[c], "-blend_alpha") && c < argc - 1) { blend_alpha = 1; background_color = strtol(argv[++c], NULL, 16); // <- parses '0x' prefix background_color = background_color & 0x00ffffffu; } else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) { ++c; if (!strcmp(argv[c], "none")) { config.alpha_filtering = 0; } else if (!strcmp(argv[c], "fast")) { config.alpha_filtering = 1; } else if (!strcmp(argv[c], "best")) { config.alpha_filtering = 2; } else { fprintf(stderr, "Error! Unrecognized alpha filter: %s\n", argv[c]); goto Error; } } else if (!strcmp(argv[c], "-noalpha")) { keep_alpha = 0; } else if (!strcmp(argv[c], "-lossless")) { config.lossless = 1; } else if (!strcmp(argv[c], "-hint") && c < argc - 1) { ++c; if (!strcmp(argv[c], "photo")) { config.image_hint = WEBP_HINT_PHOTO; } else if (!strcmp(argv[c], "picture")) { config.image_hint = WEBP_HINT_PICTURE; } else if (!strcmp(argv[c], "graph")) { config.image_hint = WEBP_HINT_GRAPH; } else { fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]); goto Error; } } else if (!strcmp(argv[c], "-size") && c < argc - 1) { config.target_size = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-psnr") && c < argc - 1) { config.target_PSNR = (float)strtod(argv[++c], NULL); } else if (!strcmp(argv[c], "-sns") && c < argc - 1) { config.sns_strength = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-f") && c < argc - 1) { config.filter_strength = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-af")) { config.autofilter = 1; } else if (!strcmp(argv[c], "-jpeg_like")) { config.emulate_jpeg_size = 1; } else if (!strcmp(argv[c], "-mt")) { ++config.thread_level; // increase thread level } else if (!strcmp(argv[c], "-low_memory")) { config.low_memory = 1; } else if (!strcmp(argv[c], "-strong")) { config.filter_type = 1; } else if (!strcmp(argv[c], "-nostrong")) { config.filter_type = 0; } else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) { config.filter_sharpness = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-pass") && c < argc - 1) { config.pass = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-pre") && c < argc - 1) { config.preprocessing = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-segments") && c < argc - 1) { config.segments = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-partition_limit") && c < argc - 1) { config.partition_limit = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-map") && c < argc - 1) { picture.extra_info_type = strtol(argv[++c], NULL, 0); #ifdef WEBP_EXPERIMENTAL_FEATURES } else if (!strcmp(argv[c], "-444")) { picture.colorspace = WEBP_YUV444; } else if (!strcmp(argv[c], "-422")) { picture.colorspace = WEBP_YUV422; } else if (!strcmp(argv[c], "-gray")) { picture.colorspace = WEBP_YUV400; #endif } else if (!strcmp(argv[c], "-crop") && c < argc - 4) { crop = 1; crop_x = strtol(argv[++c], NULL, 0); crop_y = strtol(argv[++c], NULL, 0); crop_w = strtol(argv[++c], NULL, 0); crop_h = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-resize") && c < argc - 2) { resize_w = strtol(argv[++c], NULL, 0); resize_h = strtol(argv[++c], NULL, 0); #ifndef WEBP_DLL } else if (!strcmp(argv[c], "-noasm")) { VP8GetCPUInfo = NULL; #endif } else if (!strcmp(argv[c], "-version")) { const int version = WebPGetEncoderVersion(); printf("%d.%d.%d\n", (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); return 0; } else if (!strcmp(argv[c], "-progress")) { show_progress = 1; } else if (!strcmp(argv[c], "-quiet")) { quiet = 1; } else if (!strcmp(argv[c], "-preset") && c < argc - 1) { WebPPreset preset; ++c; if (!strcmp(argv[c], "default")) { preset = WEBP_PRESET_DEFAULT; } else if (!strcmp(argv[c], "photo")) { preset = WEBP_PRESET_PHOTO; } else if (!strcmp(argv[c], "picture")) { preset = WEBP_PRESET_PICTURE; } else if (!strcmp(argv[c], "drawing")) { preset = WEBP_PRESET_DRAWING; } else if (!strcmp(argv[c], "icon")) { preset = WEBP_PRESET_ICON; } else if (!strcmp(argv[c], "text")) { preset = WEBP_PRESET_TEXT; } else { fprintf(stderr, "Error! Unrecognized preset: %s\n", argv[c]); goto Error; } if (!WebPConfigPreset(&config, preset, config.quality)) { fprintf(stderr, "Error! Could initialize configuration with preset.\n"); goto Error; } } else if (!strcmp(argv[c], "-metadata") && c < argc - 1) { static const struct { const char* option; int flag; } kTokens[] = { { "all", METADATA_ALL }, { "none", 0 }, { "exif", METADATA_EXIF }, { "icc", METADATA_ICC }, { "xmp", METADATA_XMP }, }; const size_t kNumTokens = sizeof(kTokens) / sizeof(kTokens[0]); const char* start = argv[++c]; const char* const end = start + strlen(start); while (start < end) { size_t i; const char* token = strchr(start, ','); if (token == NULL) token = end; for (i = 0; i < kNumTokens; ++i) { if ((size_t)(token - start) == strlen(kTokens[i].option) && !strncmp(start, kTokens[i].option, strlen(kTokens[i].option))) { if (kTokens[i].flag != 0) { keep_metadata |= kTokens[i].flag; } else { keep_metadata = 0; } break; } } if (i == kNumTokens) { fprintf(stderr, "Error! Unknown metadata type '%.*s'\n", (int)(token - start), start); HelpLong(); return -1; } start = token + 1; } #ifdef HAVE_WINCODEC_H if (keep_metadata != 0 && keep_metadata != METADATA_ICC) { // TODO(jzern): remove when -metadata is supported on all platforms. fprintf(stderr, "Warning: only ICC profile extraction is currently" " supported on this platform!\n"); } #endif } else if (!strcmp(argv[c], "-v")) { verbose = 1; } else if (!strcmp(argv[c], "--")) { if (c < argc - 1) in_file = argv[++c]; break; } else if (argv[c][0] == '-') { fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]); HelpLong(); return -1; } else { in_file = argv[c]; } } if (in_file == NULL) { fprintf(stderr, "No input file specified!\n"); HelpShort(); goto Error; } // Check for unsupported command line options for lossless mode and log // warning for such options. if (!quiet && config.lossless == 1) { if (config.target_size > 0 || config.target_PSNR > 0) { fprintf(stderr, "Encoding for specified size or PSNR is not supported" " for lossless encoding. Ignoring such option(s)!\n"); } if (config.partition_limit > 0) { fprintf(stderr, "Partition limit option is not required for lossless" " encoding. Ignoring this option!\n"); } } if (!WebPValidateConfig(&config)) { fprintf(stderr, "Error! Invalid configuration.\n"); goto Error; } // Read the input if (verbose) { StopwatchReset(&stop_watch); } if (!ReadPicture(in_file, &picture, keep_alpha, (keep_metadata == 0) ? NULL : &metadata)) { fprintf(stderr, "Error! Cannot read input picture file '%s'\n", in_file); goto Error; } picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL; if (blend_alpha) { WebPBlendAlpha(&picture, background_color); } if (keep_alpha == 2) { WebPCleanupTransparentArea(&picture); } if (verbose) { const double read_time = StopwatchReadAndReset(&stop_watch); fprintf(stderr, "Time to read input: %.3fs\n", read_time); } // Open the output if (out_file) { out = fopen(out_file, "wb"); if (out == NULL) { fprintf(stderr, "Error! Cannot open output file '%s'\n", out_file); goto Error; } else { if (!short_output && !quiet) { fprintf(stderr, "Saving file '%s'\n", out_file); } } if (keep_metadata == 0) { picture.writer = MyWriter; picture.custom_ptr = (void*)out; } else { picture.writer = WebPMemoryWrite; picture.custom_ptr = (void*)&memory_writer; } } else { out = NULL; if (!quiet && !short_output) { fprintf(stderr, "No output file specified (no -o flag). Encoding will\n"); fprintf(stderr, "be performed, but its results discarded.\n\n"); } } if (!quiet) { picture.stats = &stats; picture.user_data = (void*)in_file; } // Compress if (verbose) { StopwatchReset(&stop_watch); } if (crop != 0) { // We use self-cropping using a view. if (!WebPPictureView(&picture, crop_x, crop_y, crop_w, crop_h, &picture)) { fprintf(stderr, "Error! Cannot crop picture\n"); goto Error; } } if ((resize_w | resize_h) > 0) { if (!WebPPictureRescale(&picture, resize_w, resize_h)) { fprintf(stderr, "Error! Cannot resize picture\n"); goto Error; } } if (picture.extra_info_type > 0) { AllocExtraInfo(&picture); } if (print_distortion >= 0) { // Save original picture for later comparison WebPPictureCopy(&picture, &original_picture); } if (!WebPEncode(&config, &picture)) { fprintf(stderr, "Error! Cannot encode picture as WebP\n"); fprintf(stderr, "Error code: %d (%s)\n", picture.error_code, kErrorMessages[picture.error_code]); goto Error; } if (verbose) { const double encode_time = StopwatchReadAndReset(&stop_watch); fprintf(stderr, "Time to encode picture: %.3fs\n", encode_time); } // Write info if (dump_file) { if (picture.use_argb) { fprintf(stderr, "Warning: can't dump file (-d option) in lossless mode."); } else if (!DumpPicture(&picture, dump_file)) { fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file); } } if (keep_metadata != 0) { if (out != NULL) { if (!WriteWebPWithMetadata(out, &picture, &memory_writer, &metadata, keep_metadata, &metadata_written)) { fprintf(stderr, "Error writing WebP file with metadata!\n"); goto Error; } } else { // output is disabled, just display the metadata stats. const struct { const MetadataPayload* const payload; int flag; } *iter, info[] = { { &metadata.exif, METADATA_EXIF }, { &metadata.iccp, METADATA_ICC }, { &metadata.xmp, METADATA_XMP }, { NULL, 0 } }; uint32_t unused1 = 0; uint64_t unused2 = 0; for (iter = info; iter->payload != NULL; ++iter) { if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag), 0, &unused1, &unused2)) { metadata_written |= iter->flag; } } } } if (!quiet) { if (config.lossless) { PrintExtraInfoLossless(&picture, short_output, in_file); } else { PrintExtraInfoLossy(&picture, short_output, config.low_memory, in_file); } if (!short_output) { PrintMetadataInfo(&metadata, metadata_written); } } if (!quiet && !short_output && print_distortion >= 0) { // print distortion static const char* distortion_names[] = { "PSNR", "SSIM", "LSIM" }; float values[5]; // Comparison is performed in YUVA colorspace. if (original_picture.use_argb && !WebPPictureARGBToYUVA(&original_picture, WEBP_YUV420A)) { fprintf(stderr, "Error while converting original picture to YUVA.\n"); goto Error; } if (picture.use_argb && !WebPPictureARGBToYUVA(&picture, WEBP_YUV420A)) { fprintf(stderr, "Error while converting compressed picture to YUVA.\n"); goto Error; } if (!WebPPictureDistortion(&picture, &original_picture, print_distortion, values)) { fprintf(stderr, "Error while computing the distortion.\n"); goto Error; } fprintf(stderr, "%s: Y:%.2f U:%.2f V:%.2f A:%.2f Total:%.2f\n", distortion_names[print_distortion], values[0], values[1], values[2], values[3], values[4]); } return_value = 0; Error: free(memory_writer.mem); free(picture.extra_info); MetadataFree(&metadata); WebPPictureFree(&picture); WebPPictureFree(&original_picture); if (out != NULL) { fclose(out); } return return_value; } //------------------------------------------------------------------------------ libwebp-0.4.0/examples/gif2webp_util.h0000644000014400001440000000575012255002107014601 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Helper structs and methods for gif2webp tool. // // Author: Urvang (urvang@google.com) #ifndef WEBP_EXAMPLES_GIF2WEBP_UTIL_H_ #define WEBP_EXAMPLES_GIF2WEBP_UTIL_H_ #include #include "webp/mux.h" #ifdef __cplusplus extern "C" { #endif //------------------------------------------------------------------------------ // Helper utilities. #define WEBP_UTIL_TRANSPARENT_COLOR 0x00ffffff struct WebPPicture; typedef struct { int x_offset, y_offset, width, height; } WebPFrameRect; // Clear pixels in 'picture' within given 'rect' to transparent color. void WebPUtilClearPic(struct WebPPicture* const picture, const WebPFrameRect* const rect); //------------------------------------------------------------------------------ // Frame cache. typedef struct WebPFrameCache WebPFrameCache; // Given the minimum distance between key frames 'kmin' and maximum distance // between key frames 'kmax', returns an appropriately allocated cache object. // If 'allow_mixed' is true, the subsequent calls to WebPFrameCacheAddFrame() // will heuristically pick lossy or lossless compression for each frame. // Use WebPFrameCacheDelete() to deallocate the 'cache'. WebPFrameCache* WebPFrameCacheNew(int width, int height, size_t kmin, size_t kmax, int allow_mixed); // Release all the frame data from 'cache' and free 'cache'. void WebPFrameCacheDelete(WebPFrameCache* const cache); // Given an image described by 'frame', 'info' and 'orig_rect', optimize it for // WebP, encode it and add it to 'cache'. // This takes care of frame disposal too, according to 'info->dispose_method'. int WebPFrameCacheAddFrame(WebPFrameCache* const cache, const WebPConfig* const config, const WebPFrameRect* const orig_rect, WebPPicture* const frame, WebPMuxFrameInfo* const info); // Flush the *ready* frames from cache and add them to 'mux'. If 'verbose' is // true, prints the information about these frames. WebPMuxError WebPFrameCacheFlush(WebPFrameCache* const cache, int verbose, WebPMux* const mux); // Similar to 'WebPFrameCacheFlushFrames()', but flushes *all* the frames. WebPMuxError WebPFrameCacheFlushAll(WebPFrameCache* const cache, int verbose, WebPMux* const mux); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_GIF2WEBP_UTIL_H_ libwebp-0.4.0/examples/jpegdec.c0000644000014400001440000002175312255002107013434 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // JPEG decode. #include "./jpegdec.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef WEBP_HAVE_JPEG #include #include #include #include #include "webp/encode.h" #include "./metadata.h" // ----------------------------------------------------------------------------- // Metadata processing #ifndef JPEG_APP1 # define JPEG_APP1 (JPEG_APP0 + 1) #endif #ifndef JPEG_APP2 # define JPEG_APP2 (JPEG_APP0 + 2) #endif typedef struct { const uint8_t* data; size_t data_length; int seq; // this segment's sequence number [1, 255] for use in reassembly. } ICCPSegment; static void SaveMetadataMarkers(j_decompress_ptr dinfo) { const unsigned int max_marker_length = 0xffff; jpeg_save_markers(dinfo, JPEG_APP1, max_marker_length); // Exif/XMP jpeg_save_markers(dinfo, JPEG_APP2, max_marker_length); // ICC profile } static int CompareICCPSegments(const void* a, const void* b) { const ICCPSegment* s1 = (const ICCPSegment*)a; const ICCPSegment* s2 = (const ICCPSegment*)b; return s1->seq - s2->seq; } // Extract ICC profile segments from the marker list in 'dinfo', reassembling // and storing them in 'iccp'. // Returns true on success and false for memory errors and corrupt profiles. static int StoreICCP(j_decompress_ptr dinfo, MetadataPayload* const iccp) { // ICC.1:2010-12 (4.3.0.0) Annex B.4 Embedding ICC Profiles in JPEG files static const char kICCPSignature[] = "ICC_PROFILE"; static const size_t kICCPSignatureLength = 12; // signature includes '\0' static const size_t kICCPSkipLength = 14; // signature + seq & count int expected_count = 0; int actual_count = 0; int seq_max = 0; size_t total_size = 0; ICCPSegment iccp_segments[255]; jpeg_saved_marker_ptr marker; memset(iccp_segments, 0, sizeof(iccp_segments)); for (marker = dinfo->marker_list; marker != NULL; marker = marker->next) { if (marker->marker == JPEG_APP2 && marker->data_length > kICCPSkipLength && !memcmp(marker->data, kICCPSignature, kICCPSignatureLength)) { // ICC_PROFILE\0; 'seq' starts at 1. const int seq = marker->data[kICCPSignatureLength]; const int count = marker->data[kICCPSignatureLength + 1]; const size_t segment_size = marker->data_length - kICCPSkipLength; ICCPSegment* segment; if (segment_size == 0 || count == 0 || seq == 0) { fprintf(stderr, "[ICCP] size (%d) / count (%d) / sequence number (%d)" " cannot be 0!\n", (int)segment_size, seq, count); return 0; } if (expected_count == 0) { expected_count = count; } else if (expected_count != count) { fprintf(stderr, "[ICCP] Inconsistent segment count (%d / %d)!\n", expected_count, count); return 0; } segment = iccp_segments + seq - 1; if (segment->data_length != 0) { fprintf(stderr, "[ICCP] Duplicate segment number (%d)!\n" , seq); return 0; } segment->data = marker->data + kICCPSkipLength; segment->data_length = segment_size; segment->seq = seq; total_size += segment_size; if (seq > seq_max) seq_max = seq; ++actual_count; } } if (actual_count == 0) return 1; if (seq_max != actual_count) { fprintf(stderr, "[ICCP] Discontinuous segments, expected: %d actual: %d!\n", actual_count, seq_max); return 0; } if (expected_count != actual_count) { fprintf(stderr, "[ICCP] Segment count: %d does not match expected: %d!\n", actual_count, expected_count); return 0; } // The segments may appear out of order in the file, sort them based on // sequence number before assembling the payload. qsort(iccp_segments, actual_count, sizeof(*iccp_segments), CompareICCPSegments); iccp->bytes = (uint8_t*)malloc(total_size); if (iccp->bytes == NULL) return 0; iccp->size = total_size; { int i; size_t offset = 0; for (i = 0; i < seq_max; ++i) { memcpy(iccp->bytes + offset, iccp_segments[i].data, iccp_segments[i].data_length); offset += iccp_segments[i].data_length; } } return 1; } // Returns true on success and false for memory errors and corrupt profiles. // The caller must use MetadataFree() on 'metadata' in all cases. static int ExtractMetadataFromJPEG(j_decompress_ptr dinfo, Metadata* const metadata) { static const struct { int marker; const char* signature; size_t signature_length; size_t storage_offset; } kJPEGMetadataMap[] = { // Exif 2.2 Section 4.7.2 Interoperability Structure of APP1 ... { JPEG_APP1, "Exif\0", 6, METADATA_OFFSET(exif) }, // XMP Specification Part 3 Section 3 Embedding XMP Metadata ... #JPEG // TODO(jzern) Add support for 'ExtendedXMP' { JPEG_APP1, "http://ns.adobe.com/xap/1.0/", 29, METADATA_OFFSET(xmp) }, { 0, NULL, 0, 0 }, }; jpeg_saved_marker_ptr marker; // Treat ICC profiles separately as they may be segmented and out of order. if (!StoreICCP(dinfo, &metadata->iccp)) return 0; for (marker = dinfo->marker_list; marker != NULL; marker = marker->next) { int i; for (i = 0; kJPEGMetadataMap[i].marker != 0; ++i) { if (marker->marker == kJPEGMetadataMap[i].marker && marker->data_length > kJPEGMetadataMap[i].signature_length && !memcmp(marker->data, kJPEGMetadataMap[i].signature, kJPEGMetadataMap[i].signature_length)) { MetadataPayload* const payload = (MetadataPayload*)((uint8_t*)metadata + kJPEGMetadataMap[i].storage_offset); if (payload->bytes == NULL) { const char* marker_data = (const char*)marker->data + kJPEGMetadataMap[i].signature_length; const size_t marker_data_length = marker->data_length - kJPEGMetadataMap[i].signature_length; if (!MetadataCopy(marker_data, marker_data_length, payload)) return 0; } else { fprintf(stderr, "Ignoring additional '%s' marker\n", kJPEGMetadataMap[i].signature); } } } } return 1; } #undef JPEG_APP1 #undef JPEG_APP2 // ----------------------------------------------------------------------------- // JPEG decoding struct my_error_mgr { struct jpeg_error_mgr pub; jmp_buf setjmp_buffer; }; static void my_error_exit(j_common_ptr dinfo) { struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err; dinfo->err->output_message(dinfo); longjmp(myerr->setjmp_buffer, 1); } int ReadJPEG(FILE* in_file, WebPPicture* const pic, Metadata* const metadata) { int ok = 0; int stride, width, height; struct jpeg_decompress_struct dinfo; struct my_error_mgr jerr; uint8_t* rgb = NULL; JSAMPROW buffer[1]; dinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { Error: MetadataFree(metadata); jpeg_destroy_decompress(&dinfo); goto End; } jpeg_create_decompress(&dinfo); jpeg_stdio_src(&dinfo, in_file); if (metadata != NULL) SaveMetadataMarkers(&dinfo); jpeg_read_header(&dinfo, TRUE); dinfo.out_color_space = JCS_RGB; dinfo.do_fancy_upsampling = TRUE; jpeg_start_decompress(&dinfo); if (dinfo.output_components != 3) { goto Error; } width = dinfo.output_width; height = dinfo.output_height; stride = dinfo.output_width * dinfo.output_components * sizeof(*rgb); rgb = (uint8_t*)malloc(stride * height); if (rgb == NULL) { goto End; } buffer[0] = (JSAMPLE*)rgb; while (dinfo.output_scanline < dinfo.output_height) { if (jpeg_read_scanlines(&dinfo, buffer, 1) != 1) { goto End; } buffer[0] += stride; } if (metadata != NULL) { ok = ExtractMetadataFromJPEG(&dinfo, metadata); if (!ok) { fprintf(stderr, "Error extracting JPEG metadata!\n"); goto Error; } } jpeg_finish_decompress(&dinfo); jpeg_destroy_decompress(&dinfo); // WebP conversion. pic->width = width; pic->height = height; ok = WebPPictureImportRGB(pic, rgb, stride); if (!ok) goto Error; End: free(rgb); return ok; } #else // !WEBP_HAVE_JPEG int ReadJPEG(FILE* in_file, struct WebPPicture* const pic, struct Metadata* const metadata) { (void)in_file; (void)pic; (void)metadata; fprintf(stderr, "JPEG support not compiled. Please install the libjpeg " "development package before building.\n"); return 0; } #endif // WEBP_HAVE_JPEG // ----------------------------------------------------------------------------- libwebp-0.4.0/examples/pngdec.c0000644000014400001440000002174112255002107013270 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // PNG decode. #include "./pngdec.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef WEBP_HAVE_PNG #include #include // note: this must be included *after* png.h #include #include #include "webp/encode.h" #include "./metadata.h" static void PNGAPI error_function(png_structp png, png_const_charp error) { if (error != NULL) fprintf(stderr, "libpng error: %s\n", error); longjmp(png_jmpbuf(png), 1); } // Converts the NULL terminated 'hexstring' which contains 2-byte character // representations of hex values to raw data. // 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs, // e.g., 7af2..., separated by any number of newlines. // 'expected_length' is the anticipated processed size. // On success the raw buffer is returned with its length equivalent to // 'expected_length'. NULL is returned if the processed length is less than // 'expected_length' or any character aside from those above is encountered. // The returned buffer must be freed by the caller. static uint8_t* HexStringToBytes(const char* hexstring, size_t expected_length) { const char* src = hexstring; size_t actual_length = 0; uint8_t* const raw_data = (uint8_t*)malloc(expected_length); uint8_t* dst; if (raw_data == NULL) return NULL; for (dst = raw_data; actual_length < expected_length && *src != '\0'; ++src) { char* end; char val[3]; if (*src == '\n') continue; val[0] = *src++; val[1] = *src; val[2] = '\0'; *dst++ = (uint8_t)strtol(val, &end, 16); if (end != val + 2) break; ++actual_length; } if (actual_length != expected_length) { free(raw_data); return NULL; } return raw_data; } static int ProcessRawProfile(const char* profile, size_t profile_len, MetadataPayload* const payload) { const char* src = profile; char* end; int expected_length; if (profile == NULL || profile_len == 0) return 0; // ImageMagick formats 'raw profiles' as // '\n\n(%8lu)\n\n'. if (*src != '\n') { fprintf(stderr, "Malformed raw profile, expected '\\n' got '\\x%.2X'\n", *src); return 0; } ++src; // skip the profile name and extract the length. while (*src != '\0' && *src++ != '\n') {} expected_length = (int)strtol(src, &end, 10); if (*end != '\n') { fprintf(stderr, "Malformed raw profile, expected '\\n' got '\\x%.2X'\n", *end); return 0; } ++end; // 'end' now points to the profile payload. payload->bytes = HexStringToBytes(end, expected_length); if (payload->bytes == NULL) return 0; payload->size = expected_length; return 1; } static const struct { const char* name; int (*process)(const char* profile, size_t profile_len, MetadataPayload* const payload); size_t storage_offset; } kPNGMetadataMap[] = { // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData // See also: ExifTool on CPAN. { "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) }, { "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) }, // Exiftool puts exif data in APP1 chunk, too. { "Raw profile type APP1", ProcessRawProfile, METADATA_OFFSET(exif) }, // XMP Specification Part 3, Section 3 #PNG { "XML:com.adobe.xmp", MetadataCopy, METADATA_OFFSET(xmp) }, { NULL, NULL, 0 }, }; // Looks for metadata at both the beginning and end of the PNG file, giving // preference to the head. // Returns true on success. The caller must use MetadataFree() on 'metadata' in // all cases. static int ExtractMetadataFromPNG(png_structp png, png_infop const head_info, png_infop const end_info, Metadata* const metadata) { int p; for (p = 0; p < 2; ++p) { png_infop const info = (p == 0) ? head_info : end_info; png_textp text = NULL; const int num = png_get_text(png, info, &text, NULL); int i; // Look for EXIF / XMP metadata. for (i = 0; i < num; ++i, ++text) { int j; for (j = 0; kPNGMetadataMap[j].name != NULL; ++j) { if (!strcmp(text->key, kPNGMetadataMap[j].name)) { MetadataPayload* const payload = (MetadataPayload*)((uint8_t*)metadata + kPNGMetadataMap[j].storage_offset); png_size_t text_length; switch (text->compression) { #ifdef PNG_iTXt_SUPPORTED case PNG_ITXT_COMPRESSION_NONE: case PNG_ITXT_COMPRESSION_zTXt: text_length = text->itxt_length; break; #endif case PNG_TEXT_COMPRESSION_NONE: case PNG_TEXT_COMPRESSION_zTXt: default: text_length = text->text_length; break; } if (payload->bytes != NULL) { fprintf(stderr, "Ignoring additional '%s'\n", text->key); } else if (!kPNGMetadataMap[j].process(text->text, text_length, payload)) { fprintf(stderr, "Failed to process: '%s'\n", text->key); return 0; } break; } } } // Look for an ICC profile. { png_charp name; int comp_type; #if ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR << 0) < \ ((1 << 8) | (5 << 0)) png_charp profile; #else // >= libpng 1.5.0 png_bytep profile; #endif png_uint_32 len; if (png_get_iCCP(png, info, &name, &comp_type, &profile, &len) == PNG_INFO_iCCP) { if (!MetadataCopy((const char*)profile, len, &metadata->iccp)) return 0; } } } return 1; } int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha, Metadata* const metadata) { png_structp png; png_infop info = NULL; png_infop end_info = NULL; int color_type, bit_depth, interlaced; int has_alpha; int num_passes; int p; int ok = 0; png_uint_32 width, height, y; int stride; uint8_t* rgb = NULL; png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (png == NULL) { goto End; } png_set_error_fn(png, 0, error_function, NULL); if (setjmp(png_jmpbuf(png))) { Error: MetadataFree(metadata); png_destroy_read_struct(&png, &info, &end_info); goto End; } info = png_create_info_struct(png); if (info == NULL) goto Error; end_info = png_create_info_struct(png); if (end_info == NULL) goto Error; png_init_io(png, in_file); png_read_info(png, info); if (!png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, &interlaced, NULL, NULL)) goto Error; png_set_strip_16(png); png_set_packing(png); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { if (bit_depth < 8) { png_set_expand_gray_1_2_4_to_8(png); } png_set_gray_to_rgb(png); } if (png_get_valid(png, info, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png); has_alpha = 1; } else { has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA); } if (!keep_alpha) { png_set_strip_alpha(png); has_alpha = 0; } num_passes = png_set_interlace_handling(png); png_read_update_info(png, info); stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb); rgb = (uint8_t*)malloc(stride * height); if (rgb == NULL) goto Error; for (p = 0; p < num_passes; ++p) { for (y = 0; y < height; ++y) { png_bytep row = rgb + y * stride; png_read_rows(png, &row, NULL, 1); } } png_read_end(png, end_info); if (metadata != NULL && !ExtractMetadataFromPNG(png, info, end_info, metadata)) { fprintf(stderr, "Error extracting PNG metadata!\n"); goto Error; } png_destroy_read_struct(&png, &info, &end_info); pic->width = width; pic->height = height; pic->use_argb = 1; ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride) : WebPPictureImportRGB(pic, rgb, stride); if (!ok) { goto Error; } End: free(rgb); return ok; } #else // !WEBP_HAVE_PNG int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha, struct Metadata* const metadata) { (void)in_file; (void)pic; (void)keep_alpha; (void)metadata; fprintf(stderr, "PNG support not compiled. Please install the libpng " "development package before building.\n"); return 0; } #endif // WEBP_HAVE_PNG // ----------------------------------------------------------------------------- libwebp-0.4.0/examples/wicdec.h0000644000014400001440000000214312255002107013266 0ustar // Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Windows Imaging Component (WIC) decode. #ifndef WEBP_EXAMPLES_WICDEC_H_ #define WEBP_EXAMPLES_WICDEC_H_ #ifdef __cplusplus extern "C" { #endif struct Metadata; struct WebPPicture; // Reads an image from 'filename', returning the decoded output in 'pic'. // If 'keep_alpha' is true and the image has an alpha channel, the output is // RGBA otherwise it will be RGB. // Returns true on success. int ReadPictureWithWIC(const char* const filename, struct WebPPicture* const pic, int keep_alpha, struct Metadata* const metadata); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_WICDEC_H_ libwebp-0.4.0/examples/tiffdec.c0000644000014400001440000001042212255002107013426 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // TIFF decode. #include "./tiffdec.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef WEBP_HAVE_TIFF #include #include "webp/encode.h" #include "./metadata.h" static const struct { ttag_t tag; size_t storage_offset; } kTIFFMetadataMap[] = { { TIFFTAG_ICCPROFILE, METADATA_OFFSET(iccp) }, { TIFFTAG_XMLPACKET, METADATA_OFFSET(xmp) }, { 0, 0 }, }; // Returns true on success. The caller must use MetadataFree() on 'metadata' in // all cases. static int ExtractMetadataFromTIFF(TIFF* const tif, Metadata* const metadata) { int i; toff_t exif_ifd_offset; for (i = 0; kTIFFMetadataMap[i].tag != 0; ++i) { MetadataPayload* const payload = (MetadataPayload*)((uint8_t*)metadata + kTIFFMetadataMap[i].storage_offset); void* tag_data; uint32 tag_data_len; if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) && !MetadataCopy((const char*)tag_data, tag_data_len, payload)) { return 0; } } // TODO(jzern): To extract the raw EXIF directory some parsing of it would be // necessary to determine the overall size. In addition, value offsets in // individual directory entries may need to be updated as, depending on the // type, they are file based. // Exif 2.2 Section 4.6.2 Tag Structure // TIFF Revision 6.0 Part 1 Section 2 TIFF Structure #Image File Directory if (TIFFGetField(tif, TIFFTAG_EXIFIFD, &exif_ifd_offset)) { fprintf(stderr, "Warning: EXIF extraction from TIFF is unsupported.\n"); } return 1; } int ReadTIFF(const char* const filename, WebPPicture* const pic, int keep_alpha, Metadata* const metadata) { TIFF* const tif = TIFFOpen(filename, "r"); uint32 width, height; uint32* raster; int ok = 0; tdir_t dircount; if (tif == NULL) { fprintf(stderr, "Error! Cannot open TIFF file '%s'\n", filename); return 0; } dircount = TIFFNumberOfDirectories(tif); if (dircount > 1) { fprintf(stderr, "Warning: multi-directory TIFF files are not supported.\n" "Only the first will be used, %d will be ignored.\n", dircount - 1); } if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) && TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) { fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n"); return 0; } raster = (uint32*)_TIFFmalloc(width * height * sizeof(*raster)); if (raster != NULL) { if (TIFFReadRGBAImageOriented(tif, width, height, raster, ORIENTATION_TOPLEFT, 1)) { const int stride = width * sizeof(*raster); pic->width = width; pic->height = height; // TIFF data is ABGR #ifdef __BIG_ENDIAN__ TIFFSwabArrayOfLong(raster, width * height); #endif pic->use_argb = 1; ok = keep_alpha ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride) : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride); } _TIFFfree(raster); } else { fprintf(stderr, "Error allocating TIFF RGBA memory!\n"); } if (ok) { if (metadata != NULL) { ok = ExtractMetadataFromTIFF(tif, metadata); if (!ok) { fprintf(stderr, "Error extracting TIFF metadata!\n"); MetadataFree(metadata); WebPPictureFree(pic); } } } TIFFClose(tif); return ok; } #else // !WEBP_HAVE_TIFF int ReadTIFF(const char* const filename, struct WebPPicture* const pic, int keep_alpha, struct Metadata* const metadata) { (void)filename; (void)pic; (void)keep_alpha; (void)metadata; fprintf(stderr, "TIFF support not compiled. Please install the libtiff " "development package before building.\n"); return 0; } #endif // WEBP_HAVE_TIFF // ----------------------------------------------------------------------------- libwebp-0.4.0/examples/metadata.c0000644000014400001440000000300412255002107013600 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Metadata types and functions. // #include "./metadata.h" #include #include #include "webp/types.h" void MetadataInit(Metadata* const metadata) { if (metadata == NULL) return; memset(metadata, 0, sizeof(*metadata)); } void MetadataPayloadDelete(MetadataPayload* const payload) { if (payload == NULL) return; free(payload->bytes); payload->bytes = NULL; payload->size = 0; } void MetadataFree(Metadata* const metadata) { if (metadata == NULL) return; MetadataPayloadDelete(&metadata->exif); MetadataPayloadDelete(&metadata->iccp); MetadataPayloadDelete(&metadata->xmp); } int MetadataCopy(const char* metadata, size_t metadata_len, MetadataPayload* const payload) { if (metadata == NULL || metadata_len == 0 || payload == NULL) return 0; payload->bytes = (uint8_t*)malloc(metadata_len); if (payload->bytes == NULL) return 0; payload->size = metadata_len; memcpy(payload->bytes, metadata, metadata_len); return 1; } // ----------------------------------------------------------------------------- libwebp-0.4.0/examples/pngdec.h0000644000014400001440000000203312255002107013266 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // PNG decode. #ifndef WEBP_EXAMPLES_PNGDEC_H_ #define WEBP_EXAMPLES_PNGDEC_H_ #include #ifdef __cplusplus extern "C" { #endif struct Metadata; struct WebPPicture; // Reads a PNG from 'in_file', returning the decoded output in 'pic'. // If 'keep_alpha' is true and the PNG has an alpha channel, the output is RGBA // otherwise it will be RGB. // Returns true on success. int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha, struct Metadata* const metadata); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_PNGDEC_H_ libwebp-0.4.0/examples/example_util.h0000644000014400001440000000231612255002107014522 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utility functions used by the example programs. // #ifndef WEBP_EXAMPLES_EXAMPLE_UTIL_H_ #define WEBP_EXAMPLES_EXAMPLE_UTIL_H_ #include "webp/types.h" #ifdef __cplusplus extern "C" { #endif // Allocates storage for entire file 'file_name' and returns contents and size // in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should // be deleted using free(). int ExUtilReadFile(const char* const file_name, const uint8_t** data, size_t* data_size); // Write a data segment into a file named 'file_name'. Returns true if ok. int ExUtilWriteFile(const char* const file_name, const uint8_t* data, size_t data_size); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_EXAMPLE_UTIL_H_ libwebp-0.4.0/examples/metadata.h0000644000014400001440000000242712255002107013615 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Metadata types and functions. // #ifndef WEBP_EXAMPLES_METADATA_H_ #define WEBP_EXAMPLES_METADATA_H_ #include "webp/types.h" #ifdef __cplusplus extern "C" { #endif typedef struct MetadataPayload { uint8_t* bytes; size_t size; } MetadataPayload; typedef struct Metadata { MetadataPayload exif; MetadataPayload iccp; MetadataPayload xmp; } Metadata; #define METADATA_OFFSET(x) offsetof(Metadata, x) void MetadataInit(Metadata* const metadata); void MetadataPayloadDelete(MetadataPayload* const payload); void MetadataFree(Metadata* const metadata); // Stores 'metadata' to 'payload->bytes', returns false on allocation error. int MetadataCopy(const char* metadata, size_t metadata_len, MetadataPayload* const payload); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_METADATA_H_ libwebp-0.4.0/examples/jpegdec.h0000644000014400001440000000172312255002107013434 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // JPEG decode. #ifndef WEBP_EXAMPLES_JPEGDEC_H_ #define WEBP_EXAMPLES_JPEGDEC_H_ #include #include "webp/types.h" #ifdef __cplusplus extern "C" { #endif struct Metadata; struct WebPPicture; // Reads a JPEG from 'in_file', returning the decoded output in 'pic'. // The output is RGB. // Returns true on success. int ReadJPEG(FILE* in_file, struct WebPPicture* const pic, struct Metadata* const metadata); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_JPEGDEC_H_ libwebp-0.4.0/examples/gif2webp.c0000644000014400001440000005406612255002107013543 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // simple tool to convert animated GIFs to WebP // // Authors: Skal (pascal.massimino@gmail.com) // Urvang (urvang@google.com) #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WEBP_HAVE_GIF #include #include "webp/encode.h" #include "webp/mux.h" #include "./example_util.h" #include "./gif2webp_util.h" #define GIF_TRANSPARENT_MASK 0x01 #define GIF_DISPOSE_MASK 0x07 #define GIF_DISPOSE_SHIFT 2 #define WHITE_COLOR 0xffffffff #define MAX_CACHE_SIZE 30 //------------------------------------------------------------------------------ static int transparent_index = -1; // Index of transparent color in the map. static void SanitizeKeyFrameIntervals(size_t* const kmin_ptr, size_t* const kmax_ptr) { size_t kmin = *kmin_ptr; size_t kmax = *kmax_ptr; int print_warning = 1; if (kmin == 0) { // Disable keyframe insertion. kmax = ~0; kmin = kmax - 1; print_warning = 0; } if (kmax == 0) { kmax = ~0; print_warning = 0; } if (kmin >= kmax) { kmin = kmax - 1; if (print_warning) { fprintf(stderr, "WARNING: Setting kmin = %d, so that kmin < kmax.\n", (int)kmin); } } else if (kmin < (kmax / 2 + 1)) { // This ensures that cache.keyframe + kmin >= kmax is always true. So, we // can flush all the frames in the ‘count_since_key_frame == kmax’ case. kmin = (kmax / 2 + 1); if (print_warning) { fprintf(stderr, "WARNING: Setting kmin = %d, so that kmin >= kmax / 2 + 1.\n", (int)kmin); } } // Limit the max number of frames that are allocated. if (kmax - kmin > MAX_CACHE_SIZE) { kmin = kmax - MAX_CACHE_SIZE; if (print_warning) { fprintf(stderr, "WARNING: Setting kmin = %d, so that kmax - kmin <= 30.\n", (int)kmin); } } *kmin_ptr = kmin; *kmax_ptr = kmax; } static void Remap(const uint8_t* const src, const GifFileType* const gif, uint32_t* dst, int len) { int i; const GifColorType* colors; const ColorMapObject* const cmap = gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap; if (cmap == NULL) return; colors = cmap->Colors; for (i = 0; i < len; ++i) { const GifColorType c = colors[src[i]]; dst[i] = (src[i] == transparent_index) ? WEBP_UTIL_TRANSPARENT_COLOR : c.Blue | (c.Green << 8) | (c.Red << 16) | (0xff << 24); } } // Read the GIF image frame. static int ReadFrame(GifFileType* const gif, WebPFrameRect* const gif_rect, WebPPicture* const webp_frame) { WebPPicture sub_image; const GifImageDesc image_desc = gif->Image; uint32_t* dst = NULL; uint8_t* tmp = NULL; int ok = 0; WebPFrameRect rect = { image_desc.Left, image_desc.Top, image_desc.Width, image_desc.Height }; *gif_rect = rect; // Use a view for the sub-picture: if (!WebPPictureView(webp_frame, rect.x_offset, rect.y_offset, rect.width, rect.height, &sub_image)) { fprintf(stderr, "Sub-image %dx%d at position %d,%d is invalid!\n", rect.width, rect.height, rect.x_offset, rect.y_offset); return 0; } dst = sub_image.argb; tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp)); if (tmp == NULL) goto End; if (image_desc.Interlace) { // Interlaced image. // We need 4 passes, with the following offsets and jumps. const int interlace_offsets[] = { 0, 4, 2, 1 }; const int interlace_jumps[] = { 8, 8, 4, 2 }; int pass; for (pass = 0; pass < 4; ++pass) { int y; for (y = interlace_offsets[pass]; y < rect.height; y += interlace_jumps[pass]) { if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End; Remap(tmp, gif, dst + y * sub_image.argb_stride, rect.width); } } } else { // Non-interlaced image. int y; for (y = 0; y < rect.height; ++y) { if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End; Remap(tmp, gif, dst + y * sub_image.argb_stride, rect.width); } } ok = 1; End: if (!ok) webp_frame->error_code = sub_image.error_code; WebPPictureFree(&sub_image); free(tmp); return ok; } static int GetBackgroundColor(const ColorMapObject* const color_map, int bgcolor_idx, uint32_t* const bgcolor) { if (transparent_index != -1 && bgcolor_idx == transparent_index) { *bgcolor = WEBP_UTIL_TRANSPARENT_COLOR; // Special case. return 1; } else if (color_map == NULL || color_map->Colors == NULL || bgcolor_idx >= color_map->ColorCount) { return 0; // Invalid color map or index. } else { const GifColorType color = color_map->Colors[bgcolor_idx]; *bgcolor = (0xff << 24) | (color.Red << 16) | (color.Green << 8) | (color.Blue << 0); return 1; } } static void DisplayGifError(const GifFileType* const gif, int gif_error) { // GIFLIB_MAJOR is only defined in libgif >= 4.2.0. // libgif 4.2.0 has retired PrintGifError() and added GifErrorString(). #if defined(GIFLIB_MAJOR) && defined(GIFLIB_MINOR) && \ ((GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2) || GIFLIB_MAJOR > 4) #if GIFLIB_MAJOR >= 5 // Static string actually, hence the const char* cast. const char* error_str = (const char*)GifErrorString( (gif == NULL) ? gif_error : gif->Error); #else const char* error_str = (const char*)GifErrorString(); (void)gif; #endif if (error_str == NULL) error_str = "Unknown error"; fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str); #else (void)gif; fprintf(stderr, "GIFLib Error %d: ", gif_error); PrintGifError(); fprintf(stderr, "\n"); #endif } static const char* const kErrorMessages[] = { "WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_BAD_DATA", "WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_NOT_ENOUGH_DATA" }; static const char* ErrorString(WebPMuxError err) { assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA); return kErrorMessages[-err]; } enum { METADATA_ICC = (1 << 0), METADATA_XMP = (1 << 1), METADATA_ALL = METADATA_ICC | METADATA_XMP }; //------------------------------------------------------------------------------ static void Help(void) { printf("Usage:\n"); printf(" gif2webp [options] gif_file -o webp_file\n"); printf("options:\n"); printf(" -h / -help ............ this help\n"); printf(" -lossy ................. Encode image using lossy compression.\n"); printf(" -mixed ................. For each frame in the image, pick lossy\n" " or lossless compression heuristically.\n"); printf(" -q ............. quality factor (0:small..100:big)\n"); printf(" -m ............... compression method (0=fast, 6=slowest)\n"); printf(" -kmin ............ Min distance between key frames\n"); printf(" -kmax ............ Max distance between key frames\n"); printf(" -f ............... filter strength (0=off..100)\n"); printf(" -metadata ..... comma separated list of metadata to\n"); printf(" "); printf("copy from the input to the output if present.\n"); printf(" " "Valid values: all, none, icc, xmp (default)\n"); printf(" -mt .................... use multi-threading if available\n"); printf("\n"); printf(" -version ............... print version number and exit.\n"); printf(" -v ..................... verbose.\n"); printf(" -quiet ................. don't print anything.\n"); printf("\n"); } //------------------------------------------------------------------------------ int main(int argc, const char *argv[]) { int verbose = 0; int gif_error = GIF_ERROR; WebPMuxError err = WEBP_MUX_OK; int ok = 0; const char *in_file = NULL, *out_file = NULL; FILE* out = NULL; GifFileType* gif = NULL; WebPConfig config; WebPPicture frame; WebPMuxFrameInfo info; WebPMuxAnimParams anim = { WHITE_COLOR, 0 }; WebPFrameCache* cache = NULL; int is_first_frame = 1; // Whether we are processing the first frame. int done; int c; int quiet = 0; WebPMux* mux = NULL; WebPData webp_data = { NULL, 0 }; int keep_metadata = METADATA_XMP; // ICC not output by default. int stored_icc = 0; // Whether we have already stored an ICC profile. int stored_xmp = 0; int default_kmin = 1; // Whether to use default kmin value. int default_kmax = 1; size_t kmin = 0; size_t kmax = 0; int allow_mixed = 0; // If true, each frame can be lossy or lossless. memset(&info, 0, sizeof(info)); info.id = WEBP_CHUNK_ANMF; info.dispose_method = WEBP_MUX_DISPOSE_BACKGROUND; info.blend_method = WEBP_MUX_BLEND; if (!WebPConfigInit(&config) || !WebPPictureInit(&frame)) { fprintf(stderr, "Error! Version mismatch!\n"); return -1; } config.lossless = 1; // Use lossless compression by default. config.image_hint = WEBP_HINT_GRAPH; // always low-color if (argc == 1) { Help(); return 0; } for (c = 1; c < argc; ++c) { if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { Help(); return 0; } else if (!strcmp(argv[c], "-o") && c < argc - 1) { out_file = argv[++c]; } else if (!strcmp(argv[c], "-lossy")) { config.lossless = 0; } else if (!strcmp(argv[c], "-mixed")) { allow_mixed = 1; config.lossless = 0; } else if (!strcmp(argv[c], "-q") && c < argc - 1) { config.quality = (float)strtod(argv[++c], NULL); } else if (!strcmp(argv[c], "-m") && c < argc - 1) { config.method = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-kmax") && c < argc - 1) { kmax = strtoul(argv[++c], NULL, 0); default_kmax = 0; } else if (!strcmp(argv[c], "-kmin") && c < argc - 1) { kmin = strtoul(argv[++c], NULL, 0); default_kmin = 0; } else if (!strcmp(argv[c], "-f") && c < argc - 1) { config.filter_strength = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-metadata") && c < argc - 1) { static const struct { const char* option; int flag; } kTokens[] = { { "all", METADATA_ALL }, { "none", 0 }, { "icc", METADATA_ICC }, { "xmp", METADATA_XMP }, }; const size_t kNumTokens = sizeof(kTokens) / sizeof(*kTokens); const char* start = argv[++c]; const char* const end = start + strlen(start); keep_metadata = 0; while (start < end) { size_t i; const char* token = strchr(start, ','); if (token == NULL) token = end; for (i = 0; i < kNumTokens; ++i) { if ((size_t)(token - start) == strlen(kTokens[i].option) && !strncmp(start, kTokens[i].option, strlen(kTokens[i].option))) { if (kTokens[i].flag != 0) { keep_metadata |= kTokens[i].flag; } else { keep_metadata = 0; } break; } } if (i == kNumTokens) { fprintf(stderr, "Error! Unknown metadata type '%.*s'\n", (int)(token - start), start); Help(); return -1; } start = token + 1; } } else if (!strcmp(argv[c], "-mt")) { ++config.thread_level; } else if (!strcmp(argv[c], "-version")) { const int enc_version = WebPGetEncoderVersion(); const int mux_version = WebPGetMuxVersion(); printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n", (enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff, enc_version & 0xff, (mux_version >> 16) & 0xff, (mux_version >> 8) & 0xff, mux_version & 0xff); return 0; } else if (!strcmp(argv[c], "-quiet")) { quiet = 1; } else if (!strcmp(argv[c], "-v")) { verbose = 1; } else if (!strcmp(argv[c], "--")) { if (c < argc - 1) in_file = argv[++c]; break; } else if (argv[c][0] == '-') { fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]); Help(); return -1; } else { in_file = argv[c]; } } // Appropriate default kmin, kmax values for lossy and lossless. if (default_kmin) { kmin = config.lossless ? 9 : 3; } if (default_kmax) { kmax = config.lossless ? 17 : 5; } SanitizeKeyFrameIntervals(&kmin, &kmax); if (!WebPValidateConfig(&config)) { fprintf(stderr, "Error! Invalid configuration.\n"); goto End; } if (in_file == NULL) { fprintf(stderr, "No input file specified!\n"); Help(); goto End; } // Start the decoder object #if defined(GIFLIB_MAJOR) && (GIFLIB_MAJOR >= 5) // There was an API change in version 5.0.0. gif = DGifOpenFileName(in_file, &gif_error); #else gif = DGifOpenFileName(in_file); #endif if (gif == NULL) goto End; // Allocate current buffer frame.width = gif->SWidth; frame.height = gif->SHeight; frame.use_argb = 1; if (!WebPPictureAlloc(&frame)) goto End; // Initialize cache cache = WebPFrameCacheNew(frame.width, frame.height, kmin, kmax, allow_mixed); if (cache == NULL) goto End; mux = WebPMuxNew(); if (mux == NULL) { fprintf(stderr, "ERROR: could not create a mux object.\n"); goto End; } // Loop over GIF images done = 0; do { GifRecordType type; if (DGifGetRecordType(gif, &type) == GIF_ERROR) goto End; switch (type) { case IMAGE_DESC_RECORD_TYPE: { WebPFrameRect gif_rect; if (!DGifGetImageDesc(gif)) goto End; if (!ReadFrame(gif, &gif_rect, &frame)) { goto End; } if (!WebPFrameCacheAddFrame(cache, &config, &gif_rect, &frame, &info)) { fprintf(stderr, "Error! Cannot encode frame as WebP\n"); fprintf(stderr, "Error code: %d\n", frame.error_code); } err = WebPFrameCacheFlush(cache, verbose, mux); if (err != WEBP_MUX_OK) { fprintf(stderr, "ERROR (%s): Could not add animation frame.\n", ErrorString(err)); goto End; } is_first_frame = 0; break; } case EXTENSION_RECORD_TYPE: { int extension; GifByteType *data = NULL; if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) { goto End; } switch (extension) { case COMMENT_EXT_FUNC_CODE: { break; // Do nothing for now. } case GRAPHICS_EXT_FUNC_CODE: { const int flags = data[1]; const int dispose = (flags >> GIF_DISPOSE_SHIFT) & GIF_DISPOSE_MASK; const int delay = data[2] | (data[3] << 8); // In 10 ms units. if (data[0] != 4) goto End; info.duration = delay * 10; // Duration is in 1 ms units for WebP. if (dispose == 3) { static int warning_printed = 0; if (!warning_printed) { fprintf(stderr, "WARNING: GIF_DISPOSE_RESTORE unsupported.\n"); warning_printed = 1; } // failsafe. TODO(urvang): emulate the correct behaviour by // recoding the whole frame. info.dispose_method = WEBP_MUX_DISPOSE_BACKGROUND; } else { info.dispose_method = (dispose == 2) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; } transparent_index = (flags & GIF_TRANSPARENT_MASK) ? data[4] : -1; if (is_first_frame) { if (!GetBackgroundColor(gif->SColorMap, gif->SBackGroundColor, &anim.bgcolor)) { fprintf(stderr, "GIF decode warning: invalid background color " "index. Assuming white background.\n"); } WebPUtilClearPic(&frame, NULL); } break; } case PLAINTEXT_EXT_FUNC_CODE: { break; } case APPLICATION_EXT_FUNC_CODE: { if (data[0] != 11) break; // Chunk is too short if (!memcmp(data + 1, "NETSCAPE2.0", 11)) { // Recognize and parse Netscape2.0 NAB extension for loop count. if (DGifGetExtensionNext(gif, &data) == GIF_ERROR) goto End; if (data == NULL) goto End; // Loop count sub-block missing. if (data[0] != 3 && data[1] != 1) break; // wrong size/marker anim.loop_count = data[2] | (data[3] << 8); if (verbose) printf("Loop count: %d\n", anim.loop_count); } else { // An extension containing metadata. // We only store the first encountered chunk of each type, and // only if requested by the user. const int is_xmp = (keep_metadata & METADATA_XMP) && !stored_xmp && !memcmp(data + 1, "XMP DataXMP", 11); const int is_icc = (keep_metadata & METADATA_ICC) && !stored_icc && !memcmp(data + 1, "ICCRGBG1012", 11); if (is_xmp || is_icc) { const char* const fourccs[2] = { "XMP " , "ICCP" }; const char* const features[2] = { "XMP" , "ICC" }; WebPData metadata = { NULL, 0 }; // Construct metadata from sub-blocks. // Usual case (including ICC profile): In each sub-block, the // first byte specifies its size in bytes (0 to 255) and the // rest of the bytes contain the data. // Special case for XMP data: In each sub-block, the first byte // is also part of the XMP payload. XMP in GIF also has a 257 // byte padding data. See the XMP specification for details. while (1) { WebPData prev_metadata = metadata; WebPData subblock; if (DGifGetExtensionNext(gif, &data) == GIF_ERROR) { WebPDataClear(&metadata); goto End; } if (data == NULL) break; // Finished. subblock.size = is_xmp ? data[0] + 1 : data[0]; assert(subblock.size > 0); subblock.bytes = is_xmp ? data : data + 1; metadata.bytes = (uint8_t*)realloc((void*)metadata.bytes, prev_metadata.size + subblock.size); if (metadata.bytes == NULL) { WebPDataClear(&prev_metadata); goto End; } metadata.size += subblock.size; memcpy((void*)(metadata.bytes + prev_metadata.size), subblock.bytes, subblock.size); } if (is_xmp) { // XMP padding data is 0x01, 0xff, 0xfe ... 0x01, 0x00. const size_t xmp_pading_size = 257; if (metadata.size > xmp_pading_size) { metadata.size -= xmp_pading_size; } } // Add metadata chunk. err = WebPMuxSetChunk(mux, fourccs[is_icc], &metadata, 1); if (verbose) { printf("%s size: %d\n", features[is_icc], (int)metadata.size); } WebPDataClear(&metadata); if (err != WEBP_MUX_OK) { fprintf(stderr, "ERROR (%s): Could not set %s chunk.\n", ErrorString(err), features[is_icc]); goto End; } if (is_icc) { stored_icc = 1; } else if (is_xmp) { stored_xmp = 1; } } } break; } default: { break; // skip } } while (data != NULL) { if (DGifGetExtensionNext(gif, &data) == GIF_ERROR) goto End; } break; } case TERMINATE_RECORD_TYPE: { done = 1; break; } default: { if (verbose) { fprintf(stderr, "Skipping over unknown record type %d\n", type); } break; } } } while (!done); // Flush any pending frames. err = WebPFrameCacheFlushAll(cache, verbose, mux); if (err != WEBP_MUX_OK) { fprintf(stderr, "ERROR (%s): Could not add animation frame.\n", ErrorString(err)); goto End; } // Finish muxing err = WebPMuxSetAnimationParams(mux, &anim); if (err != WEBP_MUX_OK) { fprintf(stderr, "ERROR (%s): Could not set animation parameters.\n", ErrorString(err)); goto End; } err = WebPMuxAssemble(mux, &webp_data); if (err != WEBP_MUX_OK) { fprintf(stderr, "ERROR (%s) assembling the WebP file.\n", ErrorString(err)); goto End; } if (out_file != NULL) { if (!ExUtilWriteFile(out_file, webp_data.bytes, webp_data.size)) { fprintf(stderr, "Error writing output file: %s\n", out_file); goto End; } if (!quiet) { printf("Saved output file: %s\n", out_file); } } else { if (!quiet) { printf("Nothing written; use -o flag to save the result.\n"); } } // All OK. ok = 1; gif_error = GIF_OK; End: WebPDataClear(&webp_data); WebPMuxDelete(mux); WebPPictureFree(&frame); WebPFrameCacheDelete(cache); if (out != NULL && out_file != NULL) fclose(out); if (gif_error != GIF_OK) { DisplayGifError(gif, gif_error); } if (gif != NULL) { DGifCloseFile(gif); } return !ok; } #else // !WEBP_HAVE_GIF int main(int argc, const char *argv[]) { fprintf(stderr, "GIF support not enabled in %s.\n", argv[0]); (void)argc; return 0; } #endif //------------------------------------------------------------------------------ libwebp-0.4.0/examples/tiffdec.h0000644000014400001440000000205212255002107013433 0ustar // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // TIFF decode. #ifndef WEBP_EXAMPLES_TIFFDEC_H_ #define WEBP_EXAMPLES_TIFFDEC_H_ #ifdef __cplusplus extern "C" { #endif struct Metadata; struct WebPPicture; // Reads a TIFF from 'filename', returning the decoded output in 'pic'. // If 'keep_alpha' is true and the TIFF has an alpha channel, the output is RGBA // otherwise it will be RGB. // Returns true on success. int ReadTIFF(const char* const filename, struct WebPPicture* const pic, int keep_alpha, struct Metadata* const metadata); #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_EXAMPLES_TIFFDEC_H_ libwebp-0.4.0/examples/Makefile.am0000644000014400001440000000317512255002107013721 0ustar AM_CPPFLAGS = -I$(top_srcdir)/src bin_PROGRAMS = dwebp cwebp if BUILD_VWEBP bin_PROGRAMS += vwebp endif if WANT_MUX bin_PROGRAMS += webpmux endif if BUILD_GIF2WEBP bin_PROGRAMS += gif2webp endif noinst_LTLIBRARIES = libexampleutil.la libexampleutil_la_SOURCES = example_util.c example_util.h dwebp_SOURCES = dwebp.c stopwatch.h dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) dwebp_LDADD = libexampleutil.la $(PNG_LIBS) $(JPEG_LIBS) cwebp_SOURCES = cwebp.c metadata.c metadata.h stopwatch.h cwebp_SOURCES += jpegdec.c jpegdec.h cwebp_SOURCES += pngdec.c pngdec.h cwebp_SOURCES += tiffdec.c tiffdec.h cwebp_SOURCES += wicdec.c wicdec.h cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) cwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES) cwebp_LDADD = ../src/libwebp.la $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS) gif2webp_SOURCES = gif2webp.c gif2webp_util.c gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES) gif2webp_LDADD = libexampleutil.la ../src/mux/libwebpmux.la ../src/libwebp.la gif2webp_LDADD += $(GIF_LIBS) webpmux_SOURCES = webpmux.c webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) webpmux_LDADD = libexampleutil.la ../src/mux/libwebpmux.la ../src/libwebp.la vwebp_SOURCES = vwebp.c vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES) vwebp_LDADD = libexampleutil.la ../src/demux/libwebpdemux.la $(GL_LIBS) if BUILD_LIBWEBPDECODER dwebp_LDADD += ../src/libwebpdecoder.la vwebp_LDADD += ../src/libwebpdecoder.la else dwebp_LDADD += ../src/libwebp.la vwebp_LDADD += ../src/libwebp.la endif libwebp-0.4.0/examples/dwebp.c0000644000014400001440000006464412255002107013142 0ustar // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Command-line tool for decoding a WebP image. // // Author: Skal (pascal.massimino@gmail.com) #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WEBP_HAVE_PNG #include #endif #ifdef HAVE_WINCODEC_H #ifdef __MINGW32__ #define INITGUID // Without this GUIDs are declared extern and fail to link #endif #define CINTERFACE #define COBJMACROS #define _WIN32_IE 0x500 // Workaround bug in shlwapi.h when compiling C++ // code with COBJMACROS. #include // CreateStreamOnHGlobal() #include #include #include #endif #if defined(_WIN32) #include // for _O_BINARY #include // for _setmode() #endif #include "webp/decode.h" #include "./example_util.h" #include "./stopwatch.h" static int verbose = 0; #ifndef WEBP_DLL #ifdef __cplusplus extern "C" { #endif extern void* VP8GetCPUInfo; // opaque forward declaration. #ifdef __cplusplus } // extern "C" #endif #endif // WEBP_DLL //------------------------------------------------------------------------------ // Output types typedef enum { PNG = 0, PAM, PPM, PGM, BMP, TIFF, YUV, ALPHA_PLANE_ONLY // this is for experimenting only } OutputFileFormat; #ifdef HAVE_WINCODEC_H #define IFS(fn) \ do { \ if (SUCCEEDED(hr)) { \ hr = (fn); \ if (FAILED(hr)) fprintf(stderr, #fn " failed %08lx\n", hr); \ } \ } while (0) #ifdef __cplusplus #define MAKE_REFGUID(x) (x) #else #define MAKE_REFGUID(x) &(x) #endif static HRESULT CreateOutputStream(const char* out_file_name, int write_to_mem, IStream** stream) { HRESULT hr = S_OK; if (write_to_mem) { // Output to a memory buffer. This is freed when 'stream' is released. IFS(CreateStreamOnHGlobal(NULL, TRUE, stream)); } else { IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream)); } if (FAILED(hr)) { fprintf(stderr, "Error opening output file %s (%08lx)\n", out_file_name, hr); } return hr; } static HRESULT WriteUsingWIC(const char* out_file_name, int use_stdout, REFGUID container_guid, uint8_t* rgb, int stride, uint32_t width, uint32_t height, int has_alpha) { HRESULT hr = S_OK; IWICImagingFactory* factory = NULL; IWICBitmapFrameEncode* frame = NULL; IWICBitmapEncoder* encoder = NULL; IStream* stream = NULL; WICPixelFormatGUID pixel_format = has_alpha ? GUID_WICPixelFormat32bppBGRA : GUID_WICPixelFormat24bppBGR; IFS(CoInitialize(NULL)); IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, CLSCTX_INPROC_SERVER, MAKE_REFGUID(IID_IWICImagingFactory), (LPVOID*)&factory)); if (hr == REGDB_E_CLASSNOTREG) { fprintf(stderr, "Couldn't access Windows Imaging Component (are you running " "Windows XP SP3 or newer?). PNG support not available. " "Use -ppm or -pgm for available PPM and PGM formats.\n"); } IFS(CreateOutputStream(out_file_name, use_stdout, &stream)); IFS(IWICImagingFactory_CreateEncoder(factory, container_guid, NULL, &encoder)); IFS(IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache)); IFS(IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL)); IFS(IWICBitmapFrameEncode_Initialize(frame, NULL)); IFS(IWICBitmapFrameEncode_SetSize(frame, width, height)); IFS(IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format)); IFS(IWICBitmapFrameEncode_WritePixels(frame, height, stride, height * stride, rgb)); IFS(IWICBitmapFrameEncode_Commit(frame)); IFS(IWICBitmapEncoder_Commit(encoder)); if (SUCCEEDED(hr) && use_stdout) { HGLOBAL image; IFS(GetHGlobalFromStream(stream, &image)); if (SUCCEEDED(hr)) { HANDLE std_output = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode; const BOOL update_mode = GetConsoleMode(std_output, &mode); const void* const image_mem = GlobalLock(image); DWORD bytes_written = 0; // Clear output processing if necessary, then output the image. if (update_mode) SetConsoleMode(std_output, 0); if (!WriteFile(std_output, image_mem, (DWORD)GlobalSize(image), &bytes_written, NULL) || bytes_written != GlobalSize(image)) { hr = E_FAIL; } if (update_mode) SetConsoleMode(std_output, mode); GlobalUnlock(image); } } if (frame != NULL) IUnknown_Release(frame); if (encoder != NULL) IUnknown_Release(encoder); if (factory != NULL) IUnknown_Release(factory); if (stream != NULL) IUnknown_Release(stream); return hr; } static int WritePNG(const char* out_file_name, int use_stdout, const WebPDecBuffer* const buffer) { const uint32_t width = buffer->width; const uint32_t height = buffer->height; uint8_t* const rgb = buffer->u.RGBA.rgba; const int stride = buffer->u.RGBA.stride; const int has_alpha = (buffer->colorspace == MODE_BGRA); return SUCCEEDED(WriteUsingWIC(out_file_name, use_stdout, MAKE_REFGUID(GUID_ContainerFormatPng), rgb, stride, width, height, has_alpha)); } #elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp dummy) { (void)dummy; // remove variable-unused warning longjmp(png_jmpbuf(png), 1); } static int WritePNG(FILE* out_file, const WebPDecBuffer* const buffer) { const uint32_t width = buffer->width; const uint32_t height = buffer->height; uint8_t* const rgb = buffer->u.RGBA.rgba; const int stride = buffer->u.RGBA.stride; const int has_alpha = (buffer->colorspace == MODE_RGBA); png_structp png; png_infop info; png_uint_32 y; png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNGErrorFunction, NULL); if (png == NULL) { return 0; } info = png_create_info_struct(png); if (info == NULL) { png_destroy_write_struct(&png, NULL); return 0; } if (setjmp(png_jmpbuf(png))) { png_destroy_write_struct(&png, &info); return 0; } png_init_io(png, out_file); png_set_IHDR(png, info, width, height, 8, has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png, info); for (y = 0; y < height; ++y) { png_bytep row = rgb + y * stride; png_write_rows(png, &row, 1); } png_write_end(png, info); png_destroy_write_struct(&png, &info); return 1; } #else // !HAVE_WINCODEC_H && !WEBP_HAVE_PNG static int WritePNG(FILE* out_file, const WebPDecBuffer* const buffer) { (void)out_file; (void)buffer; fprintf(stderr, "PNG support not compiled. Please install the libpng " "development package before building.\n"); fprintf(stderr, "You can run with -ppm flag to decode in PPM format.\n"); return 0; } #endif static int WritePPM(FILE* fout, const WebPDecBuffer* const buffer, int alpha) { const uint32_t width = buffer->width; const uint32_t height = buffer->height; const uint8_t* const rgb = buffer->u.RGBA.rgba; const int stride = buffer->u.RGBA.stride; const size_t bytes_per_px = alpha ? 4 : 3; uint32_t y; if (alpha) { fprintf(fout, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\n" "TUPLTYPE RGB_ALPHA\nENDHDR\n", width, height); } else { fprintf(fout, "P6\n%d %d\n255\n", width, height); } for (y = 0; y < height; ++y) { if (fwrite(rgb + y * stride, width, bytes_per_px, fout) != bytes_per_px) { return 0; } } return 1; } static void PutLE16(uint8_t* const dst, uint32_t value) { dst[0] = (value >> 0) & 0xff; dst[1] = (value >> 8) & 0xff; } static void PutLE32(uint8_t* const dst, uint32_t value) { PutLE16(dst + 0, (value >> 0) & 0xffff); PutLE16(dst + 2, (value >> 16) & 0xffff); } #define BMP_HEADER_SIZE 54 static int WriteBMP(FILE* fout, const WebPDecBuffer* const buffer) { const int has_alpha = (buffer->colorspace != MODE_BGR); const uint32_t width = buffer->width; const uint32_t height = buffer->height; const uint8_t* const rgba = buffer->u.RGBA.rgba; const int stride = buffer->u.RGBA.stride; const uint32_t bytes_per_px = has_alpha ? 4 : 3; uint32_t y; const uint32_t line_size = bytes_per_px * width; const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4 const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE; uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 }; // bitmap file header PutLE16(bmp_header + 0, 0x4d42); // signature 'BM' PutLE32(bmp_header + 2, total_size); // size including header PutLE32(bmp_header + 6, 0); // reserved PutLE32(bmp_header + 10, BMP_HEADER_SIZE); // offset to pixel array // bitmap info header PutLE32(bmp_header + 14, 40); // DIB header size PutLE32(bmp_header + 18, width); // dimensions PutLE32(bmp_header + 22, -(int)height); // vertical flip! PutLE16(bmp_header + 26, 1); // number of planes PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel PutLE32(bmp_header + 30, 0); // no compression (BI_RGB) PutLE32(bmp_header + 34, 0); // image size (dummy) PutLE32(bmp_header + 38, 2400); // x pixels/meter PutLE32(bmp_header + 42, 2400); // y pixels/meter PutLE32(bmp_header + 46, 0); // number of palette colors PutLE32(bmp_header + 50, 0); // important color count // TODO(skal): color profile // write header if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) { return 0; } // write pixel array for (y = 0; y < height; ++y) { if (fwrite(rgba + y * stride, line_size, 1, fout) != 1) { return 0; } // write padding zeroes if (bmp_stride != line_size) { const uint8_t zeroes[3] = { 0 }; if (fwrite(zeroes, bmp_stride - line_size, 1, fout) != 1) { return 0; } } } return 1; } #undef BMP_HEADER_SIZE #define NUM_IFD_ENTRIES 15 #define EXTRA_DATA_SIZE 16 // 10b for signature/header + n * 12b entries + 4b for IFD terminator: #define EXTRA_DATA_OFFSET (10 + 12 * NUM_IFD_ENTRIES + 4) #define TIFF_HEADER_SIZE (EXTRA_DATA_OFFSET + EXTRA_DATA_SIZE) static int WriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) { const int has_alpha = (buffer->colorspace != MODE_RGB); const uint32_t width = buffer->width; const uint32_t height = buffer->height; const uint8_t* const rgba = buffer->u.RGBA.rgba; const int stride = buffer->u.RGBA.stride; const uint8_t bytes_per_px = has_alpha ? 4 : 3; // For non-alpha case, we omit tag 0x152 (ExtraSamples). const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES : NUM_IFD_ENTRIES - 1; uint8_t tiff_header[TIFF_HEADER_SIZE] = { 0x49, 0x49, 0x2a, 0x00, // little endian signature 8, 0, 0, 0, // offset to the unique IFD that follows // IFD (offset = 8). Entries must be written in increasing tag order. num_ifd_entries, 0, // Number of entries in the IFD (12 bytes each). 0x00, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 10: Width (TBD) 0x01, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 22: Height (TBD) 0x02, 0x01, 3, 0, bytes_per_px, 0, 0, 0, // 34: BitsPerSample: 8888 EXTRA_DATA_OFFSET + 0, 0, 0, 0, 0x03, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 46: Compression: none 0x06, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 58: Photometric: RGB 0x11, 0x01, 4, 0, 1, 0, 0, 0, // 70: Strips offset: TIFF_HEADER_SIZE, 0, 0, 0, // data follows header 0x12, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 82: Orientation: topleft 0x15, 0x01, 3, 0, 1, 0, 0, 0, // 94: SamplesPerPixels bytes_per_px, 0, 0, 0, 0x16, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 106: Rows per strip (TBD) 0x17, 0x01, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 118: StripByteCount (TBD) 0x1a, 0x01, 5, 0, 1, 0, 0, 0, // 130: X-resolution EXTRA_DATA_OFFSET + 8, 0, 0, 0, 0x1b, 0x01, 5, 0, 1, 0, 0, 0, // 142: Y-resolution EXTRA_DATA_OFFSET + 8, 0, 0, 0, 0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration 0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch) 0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA 0, 0, 0, 0, // 190: IFD terminator // EXTRA_DATA_OFFSET: 8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample 72, 0, 0, 0, 1, 0, 0, 0 // 72 pixels/inch, for X/Y-resolution }; uint32_t y; // Fill placeholders in IFD: PutLE32(tiff_header + 10 + 8, width); PutLE32(tiff_header + 22 + 8, height); PutLE32(tiff_header + 106 + 8, height); PutLE32(tiff_header + 118 + 8, width * bytes_per_px * height); if (!has_alpha) PutLE32(tiff_header + 178, 0); // IFD terminator // write header if (fwrite(tiff_header, sizeof(tiff_header), 1, fout) != 1) { return 0; } // write pixel values for (y = 0; y < height; ++y) { if (fwrite(rgba + y * stride, bytes_per_px, width, fout) != width) { return 0; } } return 1; } #undef TIFF_HEADER_SIZE #undef EXTRA_DATA_OFFSET #undef EXTRA_DATA_SIZE #undef NUM_IFD_ENTRIES static int WriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer) { const uint32_t width = buffer->width; const uint32_t height = buffer->height; const uint8_t* const a = buffer->u.YUVA.a; const int a_stride = buffer->u.YUVA.a_stride; uint32_t y; assert(a != NULL); fprintf(fout, "P5\n%d %d\n255\n", width, height); for (y = 0; y < height; ++y) { if (fwrite(a + y * a_stride, width, 1, fout) != 1) { return 0; } } return 1; } // format=PGM: save a grayscale PGM file using the IMC4 layout // (http://www.fourcc.org/yuv.php#IMC4). This is a very convenient format for // viewing the samples, esp. for odd dimensions. // format=YUV: just save the Y/U/V/A planes sequentially without header. static int WritePGMOrYUV(FILE* fout, const WebPDecBuffer* const buffer, OutputFileFormat format) { const int width = buffer->width; const int height = buffer->height; const WebPYUVABuffer* const yuv = &buffer->u.YUVA; int ok = 1; int y; const int pad = (format == YUV) ? 0 : 1; const int uv_width = (width + 1) / 2; const int uv_height = (height + 1) / 2; const int out_stride = (width + pad) & ~pad; const int a_height = yuv->a ? height : 0; if (format == PGM) { fprintf(fout, "P5\n%d %d\n255\n", out_stride, height + uv_height + a_height); } for (y = 0; ok && y < height; ++y) { ok &= (fwrite(yuv->y + y * yuv->y_stride, width, 1, fout) == 1); if (format == PGM) { if (width & 1) fputc(0, fout); // padding byte } } if (format == PGM) { // IMC4 layout for (y = 0; ok && y < uv_height; ++y) { ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1); ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1); } } else { for (y = 0; ok && y < uv_height; ++y) { ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1); } for (y = 0; ok && y < uv_height; ++y) { ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1); } } for (y = 0; ok && y < a_height; ++y) { ok &= (fwrite(yuv->a + y * yuv->a_stride, width, 1, fout) == 1); if (format == PGM) { if (width & 1) fputc(0, fout); // padding byte } } return ok; } static int SaveOutput(const WebPDecBuffer* const buffer, OutputFileFormat format, const char* const out_file) { FILE* fout = NULL; int needs_open_file = 1; const int use_stdout = !strcmp(out_file, "-"); int ok = 1; Stopwatch stop_watch; if (verbose) { StopwatchReset(&stop_watch); } #ifdef HAVE_WINCODEC_H needs_open_file = (format != PNG); #endif #if defined(_WIN32) if (use_stdout && _setmode(_fileno(stdout), _O_BINARY) == -1) { fprintf(stderr, "Failed to reopen stdout in O_BINARY mode.\n"); return -1; } #endif if (needs_open_file) { fout = use_stdout ? stdout : fopen(out_file, "wb"); if (fout == NULL) { fprintf(stderr, "Error opening output file %s\n", out_file); return 0; } } if (format == PNG) { #ifdef HAVE_WINCODEC_H ok &= WritePNG(out_file, use_stdout, buffer); #else ok &= WritePNG(fout, buffer); #endif } else if (format == PAM) { ok &= WritePPM(fout, buffer, 1); } else if (format == PPM) { ok &= WritePPM(fout, buffer, 0); } else if (format == BMP) { ok &= WriteBMP(fout, buffer); } else if (format == TIFF) { ok &= WriteTIFF(fout, buffer); } else if (format == PGM || format == YUV) { ok &= WritePGMOrYUV(fout, buffer, format); } else if (format == ALPHA_PLANE_ONLY) { ok &= WriteAlphaPlane(fout, buffer); } if (fout != NULL && fout != stdout) { fclose(fout); } if (ok) { if (use_stdout) { fprintf(stderr, "Saved to stdout\n"); } else { fprintf(stderr, "Saved file %s\n", out_file); } if (verbose) { const double write_time = StopwatchReadAndReset(&stop_watch); fprintf(stderr, "Time to write output: %.3fs\n", write_time); } } else { if (use_stdout) { fprintf(stderr, "Error writing to stdout !!\n"); } else { fprintf(stderr, "Error writing file %s !!\n", out_file); } } return ok; } static void Help(void) { printf("Usage: dwebp in_file [options] [-o out_file]\n\n" "Decodes the WebP image file to PNG format [Default]\n" "Use following options to convert into alternate image formats:\n" " -pam ......... save the raw RGBA samples as a color PAM\n" " -ppm ......... save the raw RGB samples as a color PPM\n" " -bmp ......... save as uncompressed BMP format\n" " -tiff ........ save as uncompressed TIFF format\n" " -pgm ......... save the raw YUV samples as a grayscale PGM\n" " file with IMC4 layout\n" " -yuv ......... save the raw YUV samples in flat layout\n" "\n" " Other options are:\n" " -version .... print version number and exit.\n" " -nofancy ..... don't use the fancy YUV420 upscaler.\n" " -nofilter .... disable in-loop filtering.\n" " -nodither .... disable dithering.\n" " -dither .. dithering strength (in 0..100)\n" " -mt .......... use multi-threading\n" " -crop ... crop output with the given rectangle\n" " -scale .......... scale the output (*after* any cropping)\n" " -alpha ....... only save the alpha plane.\n" " -incremental . use incremental decoding (useful for tests)\n" " -h ....... this help message.\n" " -v ....... verbose (e.g. print encoding/decoding times)\n" #ifndef WEBP_DLL " -noasm ....... disable all assembly optimizations.\n" #endif ); } static const char* const kStatusMessages[] = { "OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR", "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA" }; static const char* const kFormatType[] = { "unspecified", "lossy", "lossless" }; int main(int argc, const char *argv[]) { int ok = 0; const char *in_file = NULL; const char *out_file = NULL; WebPDecoderConfig config; WebPDecBuffer* const output_buffer = &config.output; WebPBitstreamFeatures* const bitstream = &config.input; OutputFileFormat format = PNG; int incremental = 0; int c; if (!WebPInitDecoderConfig(&config)) { fprintf(stderr, "Library version mismatch!\n"); return -1; } for (c = 1; c < argc; ++c) { if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { Help(); return 0; } else if (!strcmp(argv[c], "-o") && c < argc - 1) { out_file = argv[++c]; } else if (!strcmp(argv[c], "-alpha")) { format = ALPHA_PLANE_ONLY; } else if (!strcmp(argv[c], "-nofancy")) { config.options.no_fancy_upsampling = 1; } else if (!strcmp(argv[c], "-nofilter")) { config.options.bypass_filtering = 1; } else if (!strcmp(argv[c], "-pam")) { format = PAM; } else if (!strcmp(argv[c], "-ppm")) { format = PPM; } else if (!strcmp(argv[c], "-bmp")) { format = BMP; } else if (!strcmp(argv[c], "-tiff")) { format = TIFF; } else if (!strcmp(argv[c], "-version")) { const int version = WebPGetDecoderVersion(); printf("%d.%d.%d\n", (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); return 0; } else if (!strcmp(argv[c], "-pgm")) { format = PGM; } else if (!strcmp(argv[c], "-yuv")) { format = YUV; } else if (!strcmp(argv[c], "-mt")) { config.options.use_threads = 1; } else if (!strcmp(argv[c], "-nodither")) { config.options.dithering_strength = 0; } else if (!strcmp(argv[c], "-dither") && c < argc - 1) { config.options.dithering_strength = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-crop") && c < argc - 4) { config.options.use_cropping = 1; config.options.crop_left = strtol(argv[++c], NULL, 0); config.options.crop_top = strtol(argv[++c], NULL, 0); config.options.crop_width = strtol(argv[++c], NULL, 0); config.options.crop_height = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-scale") && c < argc - 2) { config.options.use_scaling = 1; config.options.scaled_width = strtol(argv[++c], NULL, 0); config.options.scaled_height = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-v")) { verbose = 1; #ifndef WEBP_DLL } else if (!strcmp(argv[c], "-noasm")) { VP8GetCPUInfo = NULL; #endif } else if (!strcmp(argv[c], "-incremental")) { incremental = 1; } else if (!strcmp(argv[c], "--")) { if (c < argc - 1) in_file = argv[++c]; break; } else if (argv[c][0] == '-') { fprintf(stderr, "Unknown option '%s'\n", argv[c]); Help(); return -1; } else { in_file = argv[c]; } } if (in_file == NULL) { fprintf(stderr, "missing input file!!\n"); Help(); return -1; } { Stopwatch stop_watch; VP8StatusCode status = VP8_STATUS_OK; size_t data_size = 0; const uint8_t* data = NULL; if (!ExUtilReadFile(in_file, &data, &data_size)) return -1; if (verbose) { StopwatchReset(&stop_watch); } status = WebPGetFeatures(data, data_size, bitstream); if (status != VP8_STATUS_OK) { goto end; } if (bitstream->has_animation) { fprintf(stderr, "Error! Decoding of an animated WebP file is not supported.\n" " Use webpmux to extract the individual frames or\n" " vwebp to view this image.\n"); } switch (format) { case PNG: #ifdef HAVE_WINCODEC_H output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR; #else output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB; #endif break; case PAM: output_buffer->colorspace = MODE_RGBA; break; case PPM: output_buffer->colorspace = MODE_RGB; // drops alpha for PPM break; case BMP: output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR; break; case TIFF: // note: force pre-multiplied alpha output_buffer->colorspace = bitstream->has_alpha ? MODE_rgbA : MODE_RGB; break; case PGM: case YUV: output_buffer->colorspace = bitstream->has_alpha ? MODE_YUVA : MODE_YUV; break; case ALPHA_PLANE_ONLY: output_buffer->colorspace = MODE_YUVA; break; default: free((void*)data); return -1; } // Decoding call. if (!incremental) { status = WebPDecode(data, data_size, &config); } else { WebPIDecoder* const idec = WebPIDecode(data, data_size, &config); if (idec == NULL) { fprintf(stderr, "Failed during WebPINewDecoder().\n"); status = VP8_STATUS_OUT_OF_MEMORY; goto end; } else { status = WebPIUpdate(idec, data, data_size); WebPIDelete(idec); } } if (verbose) { const double decode_time = StopwatchReadAndReset(&stop_watch); fprintf(stderr, "Time to decode picture: %.3fs\n", decode_time); } end: free((void*)data); ok = (status == VP8_STATUS_OK); if (!ok) { fprintf(stderr, "Decoding of %s failed.\n", in_file); fprintf(stderr, "Status: %d (%s)\n", status, kStatusMessages[status]); goto Exit; } } if (out_file != NULL) { fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. " "Now saving...\n", in_file, output_buffer->width, output_buffer->height, bitstream->has_alpha ? " (with alpha)" : "", kFormatType[bitstream->format]); ok = SaveOutput(output_buffer, format, out_file); } else { fprintf(stderr, "File %s can be decoded " "(dimensions: %d x %d %s. Format: %s).\n", in_file, output_buffer->width, output_buffer->height, bitstream->has_alpha ? " (with alpha)" : "", kFormatType[bitstream->format]); fprintf(stderr, "Nothing written; " "use -o flag to save the result as e.g. PNG.\n"); } Exit: WebPFreeDecBuffer(output_buffer); return ok ? 0 : -1; } //------------------------------------------------------------------------------ libwebp-0.4.0/examples/test_ref.ppm0000644000014400001440000014001712255002107014213 0ustar P6 128 128 255 ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐãýÐãýÐãýÐãýÒäþÒäþÒäþÒäþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÏäýÐãýÐãýÐãýÒäþÒäþÒäþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÏäûÏäûÏäûÏäûÐåýÐåýÐåýÐåýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÎåûÎåûÎåûÎåûÏæýÏæýÏæýÏæýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÎåûÎåùÎåùÎåùÏæúÏæúÏæúÏæýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåýÒèûÒèûÒèûÒèûÐæúÐæúÐæúÐæúÐåýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåýÐæúÒåøÒåøÒåøÒåøÒåøÒåøÐæúÐåýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÐãÿÐãÿÐãÿÏäýÏäýÏäýÐãýÒäþÒåýÒåýÒåýÏáóÏáóÏáóÏáñÔåöÔåöÔåöÔåøÒåúÒåýÒåýÐåýÐåýÐåýÐåýÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒæÿÐåþÒäþÐãýÎáúÒâûÐáúÕåÿÎáýÔæÿÔæÿÓãýÏßøÉÚð·ÆÜ‡–ª‰—©›­±»ÎŸª»©³ÅÌÖèÖáòÓáñÖèøÔåö×éûÒåøÒåúÖêÿÐæúÒæþÓæþÓæþÓæþÓæþÔèÿÔèÿÔèÿÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÓãý×èÿÕãþÒßúÕäÿÌÛøÈÙò«Åm{•dqˆhtŒlvŒs{…‹y‘‡Ÿ‘—¨¤ªº°¶Æ½ÆÕÎÜêÓäóÕæ÷ÔåöÖèúÓæùÐäùÔêþÓæûÓæûÓæûÓæûÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÌáùÎãûÓåÿÕèÿÒâûÓãýÔâýÙæÿÓáû©·Òlz•\j„mz”hqŒmw‚‹¡†‰ž¥‚–‡‹ž‚”°³Å¸½Ë•›©¿ËÙÓãòÖæö׿øÔåöÖèúÕéûÐä÷ÓæûÓæûÓæûÓæûÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓèÿÒæÿÐãýÏâûÓãýÕåÿ±¿Úªr€›Wd~\i‚~‹¤˜¢½jq‡Žªz˜„…›œ²‚„š…†›‚…–—𩲴Á¯³¿–Ÿ¬±½ËÆÔäÔâòÙèùÔãôÖèúÕæùÓæûÓæûÓæûÓæûÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓèÿÉÞ÷ÚìÿÔæÿÈÙòy‰£M[vXfVc}[deo‰ipŒ‡Žªfj‡Œ¬xz—}}˜~{•qo†‘¥—–©‰ˆ˜——¤ž¡­ÆÌÚ½ÆÕ˜¢±¯¹ËÖáò×å÷Úèù׿úÖæýÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒæÿÒäþÅ×ñfwM]wLZtMZsOXq_f€jq~žrv“rs“ˆ‰©……¤ss‘vs}–ž²›š¬€€šš¥¤¨²·»Ç‹ž‘—¨ˆ‘¡­¶ÈÓÝïÚä÷ÛéúÖèúÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒæÿÏäý½ÏéXk…IZsL\vP^yN[tbi‚sx‘Ž“¬€‚Ÿ~€‚‚¢©¨Ë¡}}›qq~—œ²œž­‚…‘±´¿¤¨²„¨¬º{€Ž‰Ÿ˜ž¯³»Î×ßò×å÷ÖèúÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåýÐåýÐåþÐåþÍßù[m‡GWqLZtIWrFQmox“›Ÿ´¡¤¸‘•ªyzss¤¤Â½¹Ù²°Ì‰‹£lm„z{vx‰œž««¯¹ÌÏÚ“›Œš›ž©˜›¨„‘•£ª°ÀÔÚê×âó׿úÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏåÿÏåÿÏæþÏæþÎãúÏåùÖêÿÒåýºÍæk~šJXvLWvLTqFNkQXtlqˆÆÈÚ£¥²áäï··Ä…„–£¢·ÎÍâÝÜïìëû¸¸Å£¢²yy†——£²²»ººÆˆˆ‘•–œž¤­­·•˜£‚…‘¡¥±¬±¿ÕÞíÖå÷×éûÔèúÓæùÔêþÔêþÔéÿÕéþÖêÿÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íÿ×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íýÙíýÙíýÙíýÙíý×ìû×ìû×ìû×ìû×íýÖìûÕëúÔêùÔêùÔêùÔêùÔêùÓéøÓéøÓéøÓéøÒè÷Òè÷Òè÷Òè÷ÐæöÐæöÐæöÐæöÐæöÐæöÐæöÐæöÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏåÿÏåÿÏæþÐåýÕêÿÐäùÏãø¬ÀÕVi‚IXvN\yHPpLSpHOlei†¨“•¢²²»ÚÛáÒÒÛ‚‘”“£º¹ÉÌÌÙ°°»——£ŒŒ˜yy†··À££¬žžª‹›š¡¯­´ªª³»»Åª­¸œŸªšžª£©·ÌÚêÒãóÚëûÚíÿÕéûÔêþÔéÿÕéþÙêýÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìú×ïûÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏæþÏæþÐåþÐåýÐäûÐäû½ÍãSc{FVpIWtS^}MUtLSpHOllp“•­ˆ‹š¡©Ž‘—‰•jly…‡–wy†“Ÿikxjlysv…ˆ‹šÉÍ×…ˆ“xz‡œ¦¥¯©¨±šš£­­·²¶À•˜£¦«¶‡Ž˜¦²ÀÈÖæ×è÷×éùÙêýÕéþÕéþÕéþÙêýÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìú×ïûÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏæþÐåýÐåýÒåýÒåý£³ÌTd}IWqIWrQ]{P\zOWwLTqFMjcf„z–il~x{†y}…z~ˆ]_o~€¥¨´kmzikxehw^artwˆŽ~€‡‰˜sv…iit£¢«ÂÂÌ••ž‰—}€‹‘–¡†‹•—ž©ÌÕâÖâðÝëûÜëý×éûÕéûÕéþÙêýÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìú×ïûÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓèÿÎãúÕéÿÈÜóqšIZrJXrIWrO[yJVtPXxT\{FNkV]zv}˜osX\pqv„fkw‚‡“fj{ˆŒ†‘sx„†‹˜y}Žhkei}X]kty‡‡‹œcewbbo†„°°»½½È±´½ÇËÓ·½Ä¡¦­·»Æ¶ºÅÀÇÒ×ãïÙæ÷ÙèùÖèúÙìÿÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåýÎäøÓæûÄ×ï^o‡HXqM[vDQlP\xNZxIUsLTsMUtHPm]e‚krŽSZsSWoW[pfj{qt†txŒjm]arZ^lmq‚^bv[^sdh}fj{dhyil€ehy~~‹˜–£¢¢­©©´¢¥­»¿Çª°·±·¾ÁÅËÌÏ×¶ºÅÁÈÓÚåóÚèøÛìýÖêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåýÕéþ²ÆÛTdzEUmM[tAOjWcMXwJSrS[zIQqJSr[c€^f„NWrLSoPTqINhW\sim‚X]tae}V\oX^qU[m]bwW\s]bykq„flV[pTWkqp€•“¡ªª¶˜˜¤ˆŒ”Œ—…‹²¶»·¸»ÌËÏÚÝå½Á̹ÂÏÔâòÛêûÕéûÖêýÕëýÕëýÕëýÖìþÖìþÖìþÖìþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒåý³ÄÚN^tIZpIWqHVqQ_zJXvLWvNZxEPoLWvQZyV^{W_}U\yOVsQUsTWt{€š\azSWqPUoPUlOTiV[pmr‡TXrOTmmr‡x}‘_d{X\qz}Œœœ¨›––¢z~ˆ†‰”{‰ww€Œ‹‘ÆÅÌÌÌÕ¥ª´°·ÁÅÐÞ×åöÛëúÙêúÖêýÖêýÕëýÖìþÖìþÖìþÖìþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÓèÿÒäþÔæÿÕèÿÐãýÐãýÕèÿÕèÿ¨¸ÒZhN[tN[tO]xQ_zM[vLZtL\vJZwBQoP^{Q]{W_W]~W[{UXwQUs\_}hl†TXrLOmIMkDGdDH_EI^‚‡œlq‹TXr~‚š„›TWtaeqv„¦ª´‡‹•~€qp€‡†–Œœ‚€‰‡”¡Ÿ©ÅÅг·Á¡¥°¤©³ÅÌÕÙâìÜêúÞíÿÚëûÖëúÖìû×íý×ðþÙñÿ×íýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×íý×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÔëøÔëøÔëøÓê÷Óê÷ÒéöÒéöÓê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÓèÿÒäþÖéÿÒäþÓåÿÐãýÐãý}©O_yNZvNVsLWsQ]yLWsN\wN\wHXrIZsHWtSa~S^}[abe†hi‹WXxW[yVZwZ^xTWtPTrOSqNQoBGaINc{€•^c}[_y–›²€…œX\yQVpjo}ˆ—¢¤±­°¿wv†‰ˆ›‰†šš–ª‰‡•rp}——£¿¿Ë„‡¢¥­»ÁÆÉÐÚÝé÷ÙæøÜëýÝïÿÚïþÙïþÖïýÕíû×íýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×ïû×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÕìùÕìùÔëøÓê÷Óê÷Óê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÓèÿÔæÿÓãýÖæÿÕåÿÛëÿw‡¡M]wDQlLWsLTqS[xV^{O[wS^zLWsBPkLZtO]xUa}Zbls_copž^bUXv\azW\vGJiHLjMPmFJbIObX^qZ^vy~•Ÿ¥¸w{UZq[_tty‡ty…‡‰–ž…„”‰ˆ˜£¡±¬ªº»»Èvv‚‹ŸŸ«¦ª²©¬´¤¨°¹¾ÈÛæôÛéùÛëúÙêùÛðþÙðýÖïûÕíú×íýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×ïû×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÕìùÕìùÕìùÔëøÓê÷Óê÷Óê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÔèÿÖæÿÔäþÓãý×èÿ~ލHXrHXrIWrIUqMUrQZwNVsQZwPXvNVsJVrS_yO\vU^y^eVZw^bsv“†ˆ¥y}šUZs]byX]wPTqPTqMQkNSjPViLQdSWo~‚—ž¤·jp‚]bw[_trv‡UZhZ\kkm}€šš¦±¯½À¾Ì©©¶ffsxx…‰‰•Œš–š¢˜œ¤ž£­ÆÏÞÝëûÜêúÛëúÙíûÖíúÙðýÚñþÙíýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×ïû×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÕìùÕìùÕìùÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÒæþÒæþÒæþÒæþÒæþÒæþÒæþÓæþÚêÿÏÝøÎÜ÷hvHVqHVqHVqGUpHTpOWtU]zLTqLTqOVsLSpS\wOXqV]wU\v]b{ptŽjoˆkmˆz}—kp‰X]wLPhNSjTWtOSpW\vLPhMQfPUjV[rae}U[mU[mkp…X]r^bv^bvehybdseerŸŸ«©¦³¢Ÿ¬‹‰škm}fixtw„Œ˜˜¢¤±Ÿ¥³ÎÚèÜêøÙéöÞñýÙíùÙðúÕìùÚïþÚïþÚïþÚïþÚïþÚïþÚïþÚïþÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïû×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÕìùÔëøÔëøÔëøÔëøÔëøÔëøÓê÷ÒéöÒéöÒéöÒæþÒæþÒæþÒæþÒæþÒæþÒæþÓæþÕåÿÎÜ÷drFToIWrESmFToMXtS^zU]zHPmLSpJQoU\y\c€sw”[_w\ax^czdi€chchdf_bzSWoNSjX]r\ax\azOTmPUlae}QVmHMdLPjINhMQfdj}y~“ejVZojm‚€–‹œŽ‡‡“¨¦°žž¨y{‹…‡˜€‚‘z}Œ}{Œœ‘‘ž¨ª·•›©ÀÉÙÙäòÙæôÚê÷ÜïúÙíùÛòýÚïýÚïþÚïþÚïþÚïþÚïþÚïþÚïþÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïû×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷ÒéöÒéöÒæþÒæþÒæþÒæþÒæþÒæþÒæþÓæþÕãþw‚žHTpMXtO[wLWsNZvT_{P\xLTqIQoLSpOSq\_~il‹„¡mpˆSVkdh}…ˆW[p[^sUZoNShV[r_h~^fzw“qx‘PWqPXockDJdGNjNUqFMiXawt}€ˆœV[rSUmtw‘¦”–¨ª››¤±°·‰‹xz‡‚”„†—‹ž}{Œ”“£œš¨´´Á‘–¤¦°½ËÖâÜëöÝíøÝðù×íöÚïúÚïýÚïþÚïþÚïþÚïþÚïþÚïþÚïþÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïû×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÔëøÔëøÔëøÔëøÔëøÔëøÓê÷ÒéöÒæÿÒæþÒæþÒæþÒæþÓæþÓæþÕåþ}‹¥DOkIUqMXtJVrMXtP\xS^zLWvHPpGNkELiNQodh…Œª¦©Ä›ž³[^r{“ilSVkQUjMQfGLaJSf_h{ltˆW_vT[t^eJSiGNhNUqLSoFMjFMiIPjrzV^tLPhOQlxz“˜š°„…š‡†–˜¸·¾•”‚‚„†—„†—xw‰ts„Ÿ››¨´´Á«­º—œ¨©°ºÍÙâÛêòÚêôßòûÜòúÚïýÚïþÚïþÚïþÚïþÚïþÚïþÚïýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïù×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷ÓèÿÐåþÓåÿÓåÿÒåýÓãûÔäúm{•LWsJSpJSpNVsT\yZbXa~NVvGOqFLoGMmIPlQXrbj~𢴴ºÍˆ¢fk€im‚\axNSjJOfQVmLPeV[p^cxchFIfMTqHOlFOjNUqZa}FIfQUrMPmTWtej„MQkMQkWZt}šxz“[\rbasfev˜–¤›‹˜ŽŒœŸœ°]\oa_r‹‰šŸŸ¬ÄÄл»Ç¤¤­¡¤¯¦­·Ë×ÞÝìôÝð÷ÝðùÜïúÜíýÜíýÜíýÜñÿÜñÿÛòÿÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóûÛòúÛòúÚñùÚñùÚñùÚñùÚñùÚñùÙðøÙðúÙðúÙðú×ïù×ïù×ïù×ïù×ïù×ïù×ïù×ïùÖíøÖíøÖíøÖíøÕì÷Õì÷Õì÷Õì÷ÔëöÔëöÔëöÓêôÐãýÖéÿÓæþÔäýÔäý×åÿp~—TazNVsLTsLTsNVvV^~V^~NVvEMlGMpNTwLSpFMi[cypxŒ¦¶«´Ä^cx_d{\axW\sTXpNSjNSj\avioZ^sdi‚FIfGNkIOpGOlSZvfk…^c}}›[_yPTqei†OTmNSlbdª]_x]^t{zzyŒœšªŽŒœ•Ÿ—“¤ž›¯]Zm[Zlkj}›¬³³¿º¹Â¾½Ä¬¬¶¨­´±»ÄÐÝäßñøÚêôÝíúÝíúÜïúÜïúÜñýÜñýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÕìôÕìôÕìôÕìôÔëóÔëóÔëóÓêò×éûÒãöÕåû׿ýÖäþ„ªIVpW_}PXxMUwMUwPXzU]NVxGOqDLmNTwIOpBIfJQmLTjmv‰¯·Épx‹W\schZ^vMQiSWoOTkPUjaez\btioae}AEbLSpLSpGOlJQkW\sswŒ£¥¾twX[vik†JMjQTopršMOh\]syx‹‰ˆ˜£¡±‹˜˜¨ˆšsp„ro‚a_r^]p‰Œ›¯¯º³²»·¶½ÀÀÉ£ª¯¶¿¿ÌÓÛêòÜì÷ÝíúÝíúÜïúÜïúÜñýÜñýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÕìôÕìôÕìôÕìôÔëóÔëóÔëóÓêòÕåô×è÷Öå÷×äùŒ˜°PZtS\wLTqQZyNVxNVxQZ{OWyHPrFNpIQqQWxW^{LSoMTmHOiS[qz‚–[cwX]wV[tHMf@E\INebf~PUjrx‹iodjzPUjHMfOVrHOlMUrFMiHMdX\qjm‚ei~š€‚›PSkik„wy‘lo‡TWl_av{zŽ¢Ÿ­Žœ¡œ«“ŽŸŒŸ¡rq„ZXkmp¡¡¬–•žº¹ÀËËÔ›ž¦ž¥¯¬·¿ËÖßÛêôÝíúÝíúÜïúÜïúÜñýÜñýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÕìôÕìôÕìôÕìôÔëóÔëóÔëóÓêò•¤¯¯¾È½ËÙz…–S\rV]wQXtV]zS[zT\{PXxLTsFNmIQqOWwT\{W^zQXtJQkELeELeNUoU]sGNhGLePTqNSlUZqMQipt‰[_tz€jq{}„ŽX^oHMdT[wOVsNVvSZwUWrHI_TUkrsˆ€•wxhi~st‰UXmMPeUXmst‰Œœ••¢­«¹•“Ÿ¤Ÿ¯ª¥·¨¤¸¢ž²¡Ÿ²qp‚mp››¦¡Ÿ©¬«²´´¾³·¿Ÿ¤¯«²»ª±»ÙäðáïýÜìùáóÿáóÿÜñýÜñýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔëóeqzit~NZeOXhPXlX]tX]w[^{QXvS[xS[xPXvNVsQZwT\yT\yMTmMTmBIcAHbMTmELeBIc@GcIMjOSpOTmjoˆrwŽhldj}MScPWaahrMScV[pT[tQXvOWtT[wVXqVWlijqs…actqs…ŒŽvx‰SVjTWlW[ohj{‘¡¦¦³œš¦›¨¶±À£ž°Ž‹žŒˆœ¢š˜«“¢›š˜¢Œ“¹¹ÂÅÅΦª´¯³¾¦«·¶¿ÌáïýÞïûáóÿáóÿÜñýÜñýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔë󀉔y‚bkxNTdV\oX\qW[p^aySZsU^yU^yQ[vS\wU^yS\wNWpFNdAI_BJa>E^GNhGNj7>Z;B_?Ba?B_BGaX]wINech}‰¢GM]DIWOUeafy_dyJSiMTmWawdl€[]ofevsr‚hfwfevml}š˜«ž¡²qtˆ_cxadx[]o€¦¦³›¨œš¦­©¸–‘£}yzw‹{z†…—•—¦œŽ–Œ‹‘©©²ÀÀɲ¶À¸»Æ´·Äœ¢°ÁÏÝÜìùáóÿÞñýÜñýÜñýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔë󅌖t{†pt€lqhlzehyTVh_avZ^sXatU]sPXoQXrT[tNUoELeAHbDH_AF_@GaELh=Da=Da@Gd>A_>A^JNkHMfAF]PUjOTiOUhX^qsyŒejOTiS[qFNdLViT\pX\pZ\m^arihzdcvjiy‹‰š£¢´rsˆy}~“xz‰wy†„„——£‰‡”~{‰‡…“‰‡—‰†…—‹‰š”–£ŒŒ—š˜¢¸·¾»»Å¾¾Ç¿¿Ë½½È¶¶Áª¯º›¦ÓãðáñþÜïúÞñýÜñýÜñýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔë󓕘£ˆŒ–‹Ž˜ÆÉÔ±±½šš¥››¨sv‚hjyps…VZmUZqPUoLOlFIhFIhGHhEFeAEc@Db@Dd>Dd>Eb>Eb?FbHOkFMiAHbAHbBIcNVlXatS[m]eydl€U]sLSlJQkLSlTWtHJhOQj]^tcdyxz‰±±¾‡†–mp}~“‘”£ž¡­–˜¥‚…‘Žvv‚Œss€‹‹—Žž€……‘““Ÿ©œ›¤­¬¶º¹Â¾½Æ¤£¬¹¸Á¾½Æ²¶À—ž©œ¨³ßïùáñûÛíùßòþÝòÿÚïúÞóÿÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓì󖉋›œ¢¢£©³´ºÙÚßÈÉϬ­³½¾Ä··À¨ª·[]obc{bdMNmIMkJLkLMlIJjFGi@Dd@Dd>Dd>Eb?Fb>EaGNjDJfBIeAHd?FbFMfDLb@H\IQeckQZpIPjFMfOVrMPoLOmPSm]_x]^spr„……‘~}“~€‘vx‡‡‰–¢¥°£¥²prvx‡Ž……‘ss€ŽŽ›~~‹šªš—¤œ›¤¤£¬ÓÒÛ¤£¬­¬¶³²»°°¹±¶À‚Œ–ÒÝéßïùáñþáóÿßôÿÝòþÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓìóÁÂÆ¤¥©Œ”•˜—˜œÞßãÎÏÓÅÆÉ¿ÀÄ´¶»··Â{zcd}hh†VWyLMoILiJMjHJhEFe@Db@Db>Eb>Eb?Fb>EaELhAHdAHdAHd>Ea@GcELh>E^ELe]e{JSiGOcNVjV^rPUoNSlOQjX\qQShbdvom€{z{}‘mpQTc[]j…ˆ“‹š†ˆ—ŒŽ††“ddqbboyy†ˆˆ•ŒŒ˜œ““Ÿ›¨›š£ž¦²±ºž¦¦¥¯¡Ÿ©š´¹Ä˜Ÿª¬¶ÀâíùáñûÞñýÛðûÝòþÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓìóÉËÍ´¶¸¦¨ª‘“•‹ŒŽ·¸ºÜÝßÚÛݸ¹»²³·ÇÇЪ©¹zxdd€__NOoDFaDFaAD^?A^@Da@Db>Eb>Eb@Gc>EaDJf?Fb=D_@Gc>Ea@GcFMi@GcJQkXawPXoJSfXasPXlGLcQVm\_tQUjSTi\^pts„vt‡‚—ik}UWfikxx{†…‡”‡‰˜‘¡^^kzz‡‚‚‰‰–‡‡”‘‘ž””¡”‘ž£¢«¡Ÿ©±°¹†…Ž£¢«¢¡ªŸŸ©²¶À­²½‹‘œÚãíãòýáóýÞóÿáöÿÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓì󩫪¾À¿‘”“ˆ‹‰mpoz}{ËÍÌßâáÖÖÖÒÒÔÁÀÇÀ¾Ë²±Ä–”«de~OOkHLaGJ_HJcFHa@E^=@]:A]=D_>Ea?Fb>Ea;B^>Ea?Fb@GcAHdMTmSZsHPfFNdS[qOWmQZpLTjJOi_d{JNc_cw]_qjl{llyŒy{VXjWZirtlpz€‚•—¦¢¤³””¡ww„}}‰‹‹—††“””¡¡¡­““Ÿ›˜¥”“œ›š£ÆÅΣ¢«ž¦ª©²°¯¸ßß黻ǔ˜£ºÄÎÝìôáóýßöþÛòúÞôýÞôýÞôýÞôýßöþßöþßöþßöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö~±²´‰‹‚…deh‘”¯°²ÎÎθ¶·ÓÐÔÜÚÞÒÐ×°­ºª©¹wvˆWXmOSdNQeNQeLOd@E\>B\:A]>Ea?Fb>Ea;B^=D_@Gc?Fb>Ea=D]=E[FNdDLbMUkS[qQZpT[tU\vV[rejTWlX\pcewjlyyy…ŽŽ›y{\^plo~y{ˆ‹Ž˜”–£vx‡~€••¢‘‘ž‚‚““Ÿ••¢‰‰–––£˜˜¥Ÿª¡Ÿ©¦¥¯Ÿž¨±°¹£¢«©¨±ª©²±°¹´³½¬°º‹‘›ßëôÛíôÞôýß÷ÿÞôýÞôýÞôýÞôýßöþßöþßöþßöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö¡¢¥”•˜‚„‡{}€dei…†‰˜šššœ›˜šÅÀÁÛÙÜÓÐÔÍÌÐÆÅ̰°¹eisV[fTXfQUfOSfAF]>B\;B^?Fb>Ea;B^=D_=D_?Fb>Ea=D_;B\BJaEMa@H^MUkIQhJSiNUoV^tdi~{”W[odhysv…z}Œ¢¢¯qp€VXjxzŒrt„vx…€„Ž“•¢fixdfvŽŽ›ww„‡‡”££°¾¾Ë——¤››¨œš¦š˜¢¯­·ÁÀÉ¥¤­´³½­¬¶°¯¸¦£«ÍÉÔ½½Æž£­©¶½Þð÷ÞôúÝöúÞôýÞôýÞôýÞôýßöþßöþßöþßöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö°±´°±´¥¦ªŽ“{}€efjmor_^c¯¬°ÕÓÖ—•˜¦¤¨”Œ‹•–œ‰‰“^blV[fSWePTeBF[?D[?B_>Ea;B^=D_=D_>Ea:A];B^=D_>EaFNdAI_;DZJQkHOiBIc;B\AHbV[pafy]arhlzy{‹ž­jiywy‹bdvjl{}Œfiv~€oq~zz‡˜˜¤ŽŽšœ‡‡“~~‰““Ÿ««¸““žœ›¤¡Ÿ©˜—¡£¢«œ¥ª©²Ÿž¨¶´»¥¢ªÒÐ×ÀÁǯ´»¥°¶Úéðßñ÷ãöýÞôúÞôýÞôýÞôýßöþßöûßöûßöûÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜôùÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö¶´¹¨¦«Ÿž£š˜~}zy~‹‰Žtsxqpt«ª¯ÄÂÉŒ“VU^WV_ljwyy…lpzTWbSVaUWfGJ^GIb@Da>Eb?Fc>Gb=Fa;E];E];E_;E_;E_?Ha?Ha?Ha?Hc@Id>Gb>GbAHdMQiNSh_ctqv„‡‰–Žvt…sr‚zy‰kjzvt…~Žyy†••¢““Ÿ––¢±°¹©¨¯ž¦•”€‰”‘žŽ›¡ž«¢¡ª—–Ÿ‹‰£¢©ÐÏÖª©°¥¤«°¯³±°´ª«¯³¸º²¶»°¶½´»ÂÖáæßïöáóúÝöúÞ÷ûÞ÷ûßøýáùýâøýá÷ûá÷ýá÷ýá÷ýá÷ýâøþâøýâøýâøýáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×ñö×ñö×ñö×ñöÖðôÖðôÖðôÕïórqv¥¤©›šžœ›Ÿ{z“‘–„‚‡wvz€†¥¤«º¹Â˜—¡a^k_]jb_mdbpss\_hNQ\\^kNQeGIbDGd>A_?Fc>Fc=Fa;E];E];E_;Da;Da>Gb>G_>Gb>Gb=Fa=Fa?GdELhUZsOTi]ar€…“‚…‘sv‚yxˆkjzom~dcs~މˆ˜~~‹}}‰šš¥““œ°¯¶¬«°¨¦­›š¡•”¬«´”‘ž”‘ž¥¤­–•ž”“𢡍´³¸ÅÄÈÓÒÖ½»À¬­°ª«­º»¿»¿Å¤¨°ÀÆÍž¤«äï÷âôûÞ÷ûÝöúÜôùâúþÞ÷úß÷øãùþá÷ýá÷ýá÷ýá÷ýâøýâøýâùúâùúáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÜôøÜôøÜôøÜôøÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×òô×òô×òô×òôÖñóÖñóÖñóÕðò}{€wvzrqvvty€…°¯³¡Ÿ¤”‹‰‰ˆ‰ˆ‘š˜¢„ŽŒ‰–a^lZWe^^j[^iZ]h]_lPTeJNcGLe@Db?Fc>Fc=Fa;E_;E_;E_;Da;Da=Fa=F^=Fa=Fa=Fa=Fa?GdELh\azOTicfx€…“jly\^k{z‹_^oVUebaqqp€~Ž}}‰ss€˜–©¨¯«ª¯¯­´œ£¡Ÿ©ÆÅΨ¥²Ž›­¬¶‘šž¤¥¤«¡Ÿ¤ÂÁÆëêïÌËÏÆÆÈ±±³ÅÆÉ¾¿Å¯²º½ÀÈ“˜ŸÁÌÔßñøßöûÞôúßöûßöúãùþâúûÞ÷úá÷ýá÷ýá÷ýá÷ýâøýâøýâùúâùúáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÜôøÜôøÜôøÜôøÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×òô×òô×òô×òôÖñóÖñóÖñóÕðò¿¾Â‰ˆ\[_edi„‚‡±°´¶´¹—–›”“š‹‰„‚Œ[Zc…‚¿½É“žcao]]iVZdkoy_boNQcNQfGLeGJh?Fb>Fc=Fa;E_;E_;E_;Da;E_=F^=F^=Fa=Fa@Id>Gb>FcAHdGLeX]rcfxdiw]_leht~Žbaq\[ksr‚xw‡{z‹‚‚yy†‰‰•••ž£¢©ª©­³²¹ž¤”“œª©²¡ž«¤¢¯·¶¿Œ‹”¤£ªª©°¦¥ª©¨¬ÇÆËÁÀ޽¿¿¿Áº¹¾ÆÇ͹¹Â¾ÁɾÁÉ”ÒáéÞñøä÷þäúÿâøýá÷ûßøùáùýá÷ýá÷ýá÷ýá÷ýâøýâøýâùúâùúáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÜôøÜôøÜôøÜôøÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×òô×òô×òô×òôÖñóÖñóÖñóÕðò©¨¬´³¸edi~‚¡Ÿ¤—–›­¬±¬«°š˜Ÿ–•œž¦~}†WUb¬ª·ÍËÙhesbbmps~Z]ecfq_drMPdINeJOiAHd=Fa=Eb;Da;Da;Da;E_;E_;E];E];E_;E_>Gb;E_AIfJQmJOiW\qZ]olq_boz}‰€ml}ihxrq~}vt…tttt””Ÿ¦¬«²¬«°ª©°š˜Ÿ“‘›ž¦¥£°½ºÇ¦¥¯–•žŒ“š˜Ÿœ›Ÿ¦¥ª¿¾ÂÆÅÉÀ¾ÁÅÂÆ¿¾ÂÔÓÚ²²»»»Å¾ÁÉŸ¤¯…šÉÙáäöýÜïöá÷ûãùþãûýäýÿâøþâøþâøþâøþâøýâøýâùúâùúáùýáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛó÷Ûó÷Ûó÷Ûó÷ÚòöÚòöÚòöÚòö×òô×òô×òô×òôÖñóÖñóÖñóÕðò»º¿ÂÁÆ¡Ÿ¤Œ‹©¨¬£¢¦–•𔓗¨¦­œ›¢ž¦°¯¸‚€[Xe^\j¸¶Ä]]iX\f_ck\_jlq}fj{DH]GLcDJd>Gb=Eb;Da;Da;Da;E_;E_;E];E];E_;E_=Fa;E_?GdGNjPUoQVkSVhlqvx…y{ˆedtedtxw‡xw‡sr‚„‚“‰‰–qq~‰‰•¨¨±ÆÅ̽»À±°·½»ÂŸž¨Ž—“{y†€ˆ˜¤£ª“‘˜”¦¥ª»º¿ËÉÎÈÆÉËÈÌÂÀÅÀ¿Æ»ºÄ¿¿ÈÂÂ̰´¿}†œ¥ßï÷èùÿáôùá÷ûáùúáùýâøþâøþâøþâøþâøýâøýâùúâùúáùýáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛó÷Ûó÷Ûó÷Ûó÷ÚòöÚòöÚòöÚòö×òô×òô×òô×òôÖñóÖñóÖñóÕðòÐÏÔ¯­²¥¤©¦¥ª—–››šžœ¡‘•‘—ˆ‡Ž–•ž¸·ÀÆÄÐ^\ib_mqo}SS^Z]h[^fadohlx}FL^=AVFMf@Id=Eb=Eb;Da;Da;E_;E];E];E];E_;E_:D^:D^=EbAHdFJdNShMPb]bp„‘ž„‚“‡†–xw‡€yxˆ€šŒtt€ŽŽ—±°·º¹¾¦¥¬¹¸¿­¬¶–•ž¥£°š˜—¡š˜¢•”›š˜ŸŽ‘©¨¬»º¿ËÉÎâßãÔÎÓÄÁÆÌÈÐÏÎ×ÎÍÖ»»Å¦ª´£ª´y‚¬¸Áè÷ÿåùþßöúßøùßøûâøþâøþâøþâøþâøýâøýâùúâùúáùýáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛóôÛóôÛóôÛóôÚòóÚòóÚòóÚòó×òô×òô×òô×òôÖñóÖñóÖñóÕðòÈÇ̪©­–•𝭲©¨¬£¢¦³²·­¬±£¢¦{z‡†œ›¤¤¢¯ljwVTbVVcNP]Z]hilwbepcfqimyrv‡FL^BJaDJd?Fb>Eb=Da;Da;E_;E];E];E_;E_;E_9B]:D^;Da=D_@Ga?D[FI]ps…ŒŽœž«——¤‚‘‚‘xw‡~Ž€€‡‡”„„vv††¿¾Å²±¶ª©°–•œ‰ˆ‘¡Ÿ©¸·À©¨±»ºÄ­¬³¸·¾¡Ÿ¦—–›­¬±¾½ÁÄÂÇÍËÎÍËι·»½º¿°¯¶³²»ÁÁËÁÁ˾ÁÌ¢¦²‚‰”Ë×ÞåôûèûÿâøýßøûáùýáùþâøþâøýâøýâøýáùúáùúáùúáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛóôÛóôÛóôÛóôÚòóÚòóÚòóÚòó×òô×òô×òô×òôÖñóÖñóÖñóÕðòÇÇÉÏÏÒÀÀÂ¥¥¨““•¨¨ª··¹¯¯±›››œœœ‚…rsy˜˜¢hhtNM]NP_SUdacrllxffrllxrt}ŽfizAEZHJcJNkDGd>A_9@];B^@Ga?Fb?Fc>Eb>Eb=D_;B^;B^=D_;B\AF_DHb@B[LOcmpŽ˜›¨‹‹—zz‡Žrr~xx„tt€‹‚‚Œ¶·½¹ºÀ°±·¥¦¬•–œ«¬²³´º±²¸¯­´²±¶·¶ºº¹¾Ÿž£¡Ÿ¤½»ÀÇÆËÁÀŲ±¶´³¸º¹¾³²·ÐÏÖÆÅÌÄÂɾ½Æ´´ÀŽ‘œ•œ¥Ýêñè÷ÿåøÿá÷ýáûþáûþâúþãúûäûýãûýâýýâýýâúûâúûâúûâúûáùúáùúáùúáùúßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÞÞáÈÈ˽½¿³³¶••—““•ÀÀÂÇÇÉ«««¯¯¯º»¾‰‹Ž[^fTVcPSbX[lVXjbdsoo{±±½››¦~~‰hhtkjz^_tHI_HJeMOlFIf?B_9@\;B^>Eb>Eb>Eb>Eb>Ea=D_;B^;B^;B\@Ga>A^@E^QUjNQcUWd…••¡……‡‡“iitffrllx€€Œ‰‰•°°¹´¶»±²¸£¤ª…†Œ¯°¶¦¨­²³¹¹¸½²±¶¸·»ÁÀʏ½›šž¢¡¥»º¿ÉÈ͹¸½¬«°·¶º´³¸Ù×ÜÄÂÇÈÇÎÀ½Ç¥¤­²²»‡Œ–¥¯¹ßëôæ÷ÿäúÿáûþáûûâúûãúûäûýãûýâýýâýýâûùâûùâûùâûùáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðßßâÒÒÔššœŸ££¥““•­­°³³¶¯¯¯ŸŸŸ—˜›¯°³z~†jlyNP_QTewy‹hjyzz‡””¡ÈÈÔ\\hllyts„y{PQfEG_HJeGJhAEb=D_>Ea>Eb>Eb=Da=Da>Ea>Ea=D_;B^=D]9@Z@Da?D]PTi^bsdfswz…]]immy‰‰•{{‡jjvzz†††‘““ž¢¢«³´º¹ºÀ²³¹–—‘“˜³´º©ª°¸·»²±¶­¬±¯­²¾½Á¸·»±°´¥¤©¾½ÁÇÆËº¹¾”“—½»À·¶ºÀ¿ÄÎÍÔÇÆÏ°¯¸½½Æšž©x‰±½Æéøÿä÷þâúþáûûâúûâúûãûýãûýâýýâýýâûùâûùâûùâûùáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÌÌÎ××Ú³³¶ªª¬°°²¬¬¯ššœ””–¡¡¡¥¥¥£¤¦¤¥©˜œ¤‚…‘WZiTVhpr„\^m~Žffs““ŸZZe‰‰–¡¡­¤¦¶twˆEH]FHaLPjGJh?Fb;B^=Da=Da=Da=Da=D_>Ea>Ea=D_>E^:A[;?\@E^NQfcfx…‡”£¦±ŒŒ—€€Œww‚„„{{‡‹œŽŽš˜˜¢´¶»³´º³´º¤¥«‚ˆ¤¥«¡¢¨´³¸³²·±°´·¶ºÌËϽ»À¾½Á¹¸½¿¾Â»º¿ÆÅɘ—œÌËÏÂÁÆìëðáßæÄÂÌÇÆÏ¶¶¿°³¾y€‹‰“ë÷ÿãôûãùþáûûâúûâúûãûýãûýâýýâýýâûùâûùâûùâûùáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÄÄÆÌÌÎÏÏÒ¸¸ººº½³³¶ÂÂŬ¬¯˜˜˜“”–—˜œœŸ¨‡‰–LN]IL]qs‚lo~kjzNM]FFSOO\eeq~~‹y{ˆ…‡–_cw>@XOTmFIfAHd>Ea>Eb>Eb>Eb>Eb9@\:A]>Ea>Ea=D]=D];?\HMfHLa\_q„¬°º¯¯º““ž††‘‰‰•ŽŽšˆˆ”——£ˆˆ”¦¥¦¬¯°¶²³¹¸¹¿š›¡Ž”°±·´³¸¹¸½±°´º¹¾ÅÄÈÇÆË½»À¹¸½ÅÄÈÈÇÌÅÄȤ£¨¨¦«ÖÕÚãâæÝÜãÔÓÜËÉÓÀÀÉÍÐÛ–›¦—¢ÈÎÜë÷ÿãùþãûýâýýâýýâýýâýýãûýãûýãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÀÀ··¹ËË;¾À¨¨ª¶¶¸ÈÈËÇÇɲ²²ªªª¬­°Ÿ¡¤˜œ¤›ªGIXIL]SUdehw„‚“XWhML\^^k]]ipp{Ž‘œ¯±À“–ªILdINhHLiAHdAHd?Fc>Eb>Eb>Eb:A]:A]=D_>Ea>E^@Ga>A^AF_AEZ]arrt{‰}}ˆˆˆ”……›——£¥¥±ŸŸ«¦¦°ª«±¸¹¿¶·½­¯´±²¸†‡ª«±»º¿ÌËÏÂÁÆ«ª¯¹¸½ÍÌÐÄÂǺ¹¾·¶º½»À¾½Á±°´¿¾ÂßÞãÄÂÇÝÜãíìöÂÁËÇÇÐÐÐÜÅÇÔ”Ÿª¯½ëôÿåùþâúûâýýâýýâýýâýýãûýãûýãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÁÁĺº½ÅÅǾ¾À“¥¥¨»»¾ÁÁÄÅÅž¾¾³´·°±´¬°¸”–£LN]OQc\^macr…„”ji{TScbboZZejjs¯²ºº½É_ctVZo@E^>A^FMiBIeBIf?Fc>Eb>Eb:A];B^=D_=D_?F_>E^@Da@E^GJ_\_q{~‹z~ˆss††‘……‹‹‹–˜˜¤““ž›¤¤­ÍÎÔ»½Â³´º¤¥«Ÿ¡¦­¯´ž¤±°´¿¾ÂÏÎÓ­¬±±°´ž¢¯­²ÂÁÆ¿¾Â³²·¸·»«ª¯º¹¾¿¾ÂÍÌÐ÷öýÙ×áÄÂ̽½ÆÆÆÒ××äšœ©“¢ÉÐÛèùÿâúûâýýßþýßþýâýýãûýäûýãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÇÇÉÄÄÆ½½¿½½¿¦¦©¹¹»±±³³³³ÁÁ¿ÇÇDz³¶°±´ªª³¡¡­NM_IL]UWiik}PObqp‚edt^^kaaljjs­­·©¬·}Ž{}‘SUmFHcHLiGJhDJfAJe>Gb>Ea:A];B^>Ea=D_?F_9@Z@DaFJd=?WLOc~‚Žwz…ooz‚‚Ž——£‚‚Žˆˆ”––¢……–—•–œ³´º¿ÀÆŒ“¡¢¨½½Æ¦¨­¨¦«ÅÄÈÎÍÒ´³¸¬«°·¶ºÀ¿Ä²±¶»º¿ÅÄÈÇÆË¶´¹À¿ÄÎÍÒÜÛßÔÓ××ÖÝãâé¿ÀƬ¬¶ÀÀÌ´´ÁŒœ¡¬áð÷åùûâúûâýýâýýâýýãûýãýúãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïð‘‘‘ÀÀÀ«««ËË˾¾¾ÁÁÁ¹¹¹½½½ÄÄÁ¿¿¿ÎÎЭ¬³¯¬¹Ÿ­PMaNMbHF]qo†\[pzyŒ€\\i‚‚Žllv}~„‚‚Œ˜˜¤­¬½›²NLeNLhJMjJTlGTkANe=F^=D]:A[;?\=@]?D]?D]?B_?B_AF_?DXfmx~„‹swvvŽŽ—~~‡ww„žž«‡‡“–¥¤«‹‰“£¢«“‘˜œ›¤¯¬¹¡Ÿ©¢¡¥²²´ÏÏÒÀÀÂÆÆÈ±±³££¥±±³½½¿ÈÈËÇÇÉÂÂÅÄÄÆÇÇÉÍÍÏÌÌÎñðôöôùÈÇÌ­¬³¿¾ÅÅÄÍ‘œ–š¤¸ÂËæöýäöùëÿÿãýúãþûÞýùâþøäþùãýøâû÷âû÷áúöáúöáúöáúøßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïxxxÌÌÌÒÒÒ¶¶¶ÌÌÌœœœ‡‡‡°°°¦¦¤¢¢¢¸¸º²±¸°­º¢Ÿ­OL_LH^VTkWUlMLahfy˜˜¥ddpœœ¥ss}iho…„‹¥¤­±¯½ÉÆÚ‰†XToTTpDMeN[rDPh>G_:A[:A[>A^>A^?D]?D]?B_?B_BFc=AXZ_my~ˆtx‚ppyˆˆ‘‰‰•““Ÿ‹‹—zz‡””ŸŽ—Ÿž¥–•žŒ••”Ž—¶³À»ºÄš˜²²´ÁÁĸ¸º¿¿ÁÇÇɬ¬¯¡¡£»»¾ÆÆÈ¾¾ÀÁÁÄÀÀÂÅÅÇÌÌÎÇÇÉããåÂÂÅÒÐÕ·¶ºÀ¿Æ¿¾Å«ª³ŽŽ—¢©²áëóåöùéúþåýûáúøâÿúÞý÷ãÿùãýøâû÷âû÷áúöáúöáúöáúößù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïllj––”ÏÏÍ¿¿½¸¸¶~~{……‚¿¿½¡¡žžžœ££¥±°´©¨±«©¶HFTOM]XWjXWjSQb\\ittww‚{{…fhmomt–•œ¯­·¾»È½ºË²¯Â[WmVWpBIcQ[vISmBIe=D_>A^?B_>A^?D]?D]?D]?D]?B_BG^MSasx„xz‡zz‡Œ––£{{‡šš£……Ž‚‚Žzx…˜–£œ¥—–Ÿ—–Ÿ–•žª©°ÇÆÍ°¯³³³¶««­±±³²²´««­¿¿ÁÆÆÈ³³¶ÁÁÄÇÇÉÁÁĹ¹»½½¿ÈÈËÈÈ˽½¿ÇÇɸ·»ÁÀʏ¿ÉÈϹ¸Á‹‹”Œ›ÆÐÙíúÿèùýåùùåÿýßûöáÿùãÿùãýøâû÷âû÷áúöáúöáúöáúößù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïaa^yywÙÙÖËËÈÈÈÆ……‚wwt¡¡žŸ¡œ´´²ŸŸ¢¦¥¬œ›¤VTaLIVNN[UUbPP\EEPaalMMVMNThiokjož¢½»Â£¢«ÄÁÏ»¹Éws‡QPeFJdMTpNUqHLiEHeAEb>A^=A[?D[?D[?D]?D]?B_DHbBHXqvsv‚qq~wv†——¤……Ž‹Œ‘˜””Ÿqo}Œ‰–¥¤­¨¦°›¨›š£–»º¿¸¸º¸¸º»»¾ÄÄÆ»»¾´´·²²´íí𸸺ÅÅÇÂÂÅÅÅǽ½¿´´···¹¹¹»¨¨ªÉÉÌÄÂǺ¹¾±°·¸·¾ÈÇОž¨‚‡‘“š£Üéíâòöæúúãúùãÿùâþøäþùãýøâû÷âû÷áúöáúöáúöáúößù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïVWSopk½¾¹½¾¹Œvwr€}”•‚„²³¯³³±„„„¡¡£Œ‹–•œkjqddmTT]TT]OOXZ[aTU[NOSdeiomrˆ‡Œ¥¤©£¢©ÂÁ˦¤±qo}edtSVk?D]OTmOTmHLiBFc;?\>B\?DX?DX>BZ>B\AEb>B\?EWzsv‚oo{ml}š––Ÿ‚„‰¦““ž›rp}Ž—±°¹°­ºž¦Œ‹‘Ž“±±³ÁÁÄÄÄÆºº½ÆÆÈÆÆÈÉÉÌÌÌθ¸ºÌÌÎÇÇÉÅÅÇÀÀÂÀÀºº½²²´ºº½èèêÜÛß¿¾Â½»Â¸·¾ÍÌÕÈÈÒ‡‹•y€‰©³¹íúÿä÷÷åýûäþùáý÷åÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÜöóÜöóÜöóÜöóÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïTUPbc^}~y«¬¨¢£žbc^‡ˆ„stpklh‹Œ‡‹‹ˆ€€~€€€‡‡‰°°²°¯³ijm]^bXZ]deiZ[^\]aTUXefjooqwwy¹¹»œ›Ÿ¹¸¿Œ‹”°¯¸††“cewLOdPTiPSkOQlIMj?B_>B\?DX@EZ?D[?D]?B_?D]BH[jo}€‚{{ˆddqxx…œœ¨††‘‘›˜˜¤£¡­“xw€Ž—°¯¸±°¹˜—ž†…Œ«ª¯»»¾ÄÄÆÉÉ̾¾ÀÌÌÎÈÈËââäÍÍϸ¸ºËËÍÉÉÌÇÇÉÂÂÅÁÁÄÂÂÅ»»¾ÀÀÂÄÂÇÈÇÌÇÆÍ¨¦­ÒÐÚÅÅΟ£­{€‹†”Ôáååøøåùùãýøãÿùåÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÜöóÜöóÜöóÜöóÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïUVOef_lmf©ª£‰‹„WXQ„…~mohde^stpjkfddbaa^eeeŸŸŸŽŽŽijljkm^_b]^aefi„…‡LMOijlrrtkkkžžž‹‹——šjimfel…„}}ˆfivUWiPQfPSkOTmDGd;B\@EZAGZ@E\?D]?B_@E^BH[SWey}‡yy‚mmwww‚……‘Ž……‘šš¥Œ•Ÿž¥Ÿž¨‚‹”“œ³²»š—¤Œ‹”¤£¨»»¾ÅÅÇÕÕ×ÏÏÒÆÆÈÔÔÖÈÈËßßâ»»¾ÍÍÏÇÇÉÈÈËÌÌÎËËÍÆÆÈÂÂÅÎÎÐÇÆË¬«°¶´»«ª±º¹ÂÎÎ×¾ÁÌ{€‹‚‰Ÿ¬±ãóôæúúæþúåÿúåÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÜöóÜöóÜöóÜöóÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïUVQ[\Wfhclmffha^_Xef_cd][\U^_[^_[Z[ViifccaŽŽŒttrceddfe]_^TVUehf{}bcekmlsssiiilll‘‘‘}}}vvxxxz{z‰ˆ€‡ddpVXhTUjTVoINh@E^AGZAGZ@EZ?D[?B_@E^>BWBFWkmz€€‰llvxx„‡‡”jiytt‚‚މˆ–•œŸž¨¨¦°zy‚ˆ†“ŽŒš…‚”“—¤¤¦··¹ÄÄÆÎÎÐÎÎÐÐÐÓ××ÚÔÔÖÛÛÝÏÏÒÎÎÐÏÏÒÌÌÎËËÍÍÍÏÅÅÇÈÈËÂÁƾ½Ä´³º·¶½²±ºÒÐÚÒÒÝŒš„‰~ˆŽÞïðêýýêÿþãýøåÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷áø÷áø÷áø÷ß÷öß÷öß÷öß÷öÝôóÝôóÝôóÝôóÝôóÝôóÝôóÜóòÛòñÛòñÛòñÛòñÚñðÚñðÚñðÙðïOOM[[Xiif…†klhefbcd]cd]NOJTTQUUSQQOppmppmXXVddbjjhbb_[[XWWUffdjjjjjjffdhheddbaa^^^\iifxxxqqqttrmmmomr__iPO_LMbGIbAD\AEVLOaNQf?AZAD\?AZ?BWBFZacr††‘}}ˆkkx‰‰–ˆˆ•ddq‹ŽŽ—‡‡˜˜˜¢ªª¶‹‹—˜˜¥˜Œžž¡°°²ÀÀÂËËÍÀÀÂÏÏÒÔÔÖÈÈËÛÛÝÅÅÇÒÒÔÆÆÈÇÇÉÆÆÈÍÍÏÆÆÆËËÍÉÈϾ½Ä­¬±¥¤©³²»ÆÄÐÒÐÚ·¶¿‡‹“‘šê÷ùéûùéþúäý÷æÿùåþøäý÷äý÷ãûöãûöãûöãú÷áøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíÜñíSSSNNNkkissqqrm]^Zbc\ijeQQOLLIZZWMMJbb_ŽŽŒ^^\ZZWiifbb_\\Z[[Xbb_hheaa^ddbeecVVTddbaa^__]eeceecmmksrojieiii…„ˆ__kTScTVhQUfLP\UZeUXjEH\AEZ?AZ?BWBDXIHXlly††“}}‰‚‚Ž©©´¤¤°„„__kppyˆ””Ÿ••¢””¡¡¡­ªª³”žž¡´´···¹ËËÍÉÉÌÅÅÇÎÎÐÇÇÉÛÛÝÍÍÏÓÓÕÄÄÆÉÉÌÓÓÕÝÝßÚÚÚÆÆÈÆÅÌÄÂÉËÉΜ¡¯­·¿½ÉËÇÒÖÕÞœ£•šßíìëþûéþùæÿùæÿùåþøäý÷äý÷ãûöãûöãûöãûöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíÜñíJJJMMM]][hhefhcbc^_aZfhcTTQOOM__]TTQUUS‚‚€~~{SSPbc^]^Z[\W\]Xbc^efb^_[efbiifPPN]][eechhemmkjjhddbppmbb____Ž{}‚^^hZZeX\dU[_\biZ^jFI[@DW@DXBF[HI^TSeiivzz‡ww‚–£¤ª²³¹ÅÆÌ‰‰•bboZZfŽ““žŽŽ—““œ¶¶¿¶´¹œœž¸¸º¸¸ºÂÂÅÒÒÔÂÂÅÐÐÓÔÔÖÔÔÖÓÓÕÐÐÓÇÇÉÆÆÈÈÈË¥¥¨···»»¾ÄÂÇÉÈÍ¿¾ÂÇÆË›š£²±ºÍÉÔ¾½ÆÀÁÇŽ”˜Üêéåøöéþùäý÷æÿùåþøäý÷äý÷ãûöãûöãûöãûöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíAAALLLUUSccabc^Z[V^_Xab]WWUXXVUUSNNLXXVeec““LLI[\WWXTWXTZ[V_a\\]X\]X_a\^^\ZZW]][eeceecmmkjjhZZWffd[]\^a_vxwˆ‰Œklo]^bZ[]X]\]bcX\dDFS@BTDEZLMbTVhLJ[aam~~‰€€‰…†Œ¡¢¥¶·¹ÆÇËÆÆÒ……‘XWhbbo‹‹”„…‹——¡¤¥«ž¢¥¥¨¨¨ªÀÀ¶¶¸»»¾ËËÍÌÌÎÀÀÂÌÌÎÆÆÈÆÆÈÎÎÐÉÉÌŽŽyy{‹‹‹¨¨ªÂÂÅÀ¿Ä¿¾ÂÕÔÛ«ª±“‘›¹¶ÀÏÎ×Ö×Ý•›ŸÍÛÚèúøêÿúèÿúæÿùåþøäý÷äý÷ãûöãûöãûöãûöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíHHHNNNVVTffd]^ZNOJQSL_a\WWU\\ZPPNPPN^^\cca}}zVVTXZU_aZWXQ_aZab[\]VZ[T_a\bb_]][ZZW^^\eeceecddbUUSX[ZX[Z^a_ceddddiiihheTVSTVQ[]Z^_cQQ[IIVEDTML\^]m]]jaaliir‚ˆ}~‰‹¯±°¾¿ÁÉÉÓÎÎÛ‡†–QQ^qqz˜šŸ˜˜¢–~}ÅÅǬ¬¯¿¿ÁËËÍÀÀž¾ÀÍÍÏÆÆÈ¸¸º½½¿ÎÎÐÍÍÏÓÓÕÎÎÐÌÌί¯±¾¾ÀÉÈ͸·¾½»ÂÐÏÖ“‘˜¹¶ÀÍÌÕÜÝãÍÓ×Õãâéûùæû÷ãûöæÿùåþøäý÷äý÷ãûöãûöãûöãûöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßôñßôñÞóðßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïOOOGGGQQO]][VWSMNIUVOab]]][__]__][[XVVTaa^aa^]][TUPhibUVObc\bc\]^WWXQ^_[[[X]][VVT]][eecddbddbVXWSWXX]^[\^bdcbbbccalljWXTZ[Vbd_abdTU[JJTFFQJJVWWcaajijp\]c€„z{~}~¥¨¦±²´ÁÁËÐÐÝÍÍÚss€^^j››¤››¤¢¢«š˜¿¿Á³³¶ÅÅdz³¶ÈÈËÂÂÅËËÍÓÓÕÒÒÔªª¬ŸŸ¢¹¹»ËËÍÓÓÕÔÔÖããåééë··¹ÄÂÇËÉв±ºÂÁȯ­´¯«¶ÁÀÉÎÏÕÙÞãÛéèèúøæû÷äý÷æÿùåþøäý÷äý÷ãûöãûöãûöãûöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßôñßôñÞóðßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïZZZPPPQQOOOMPQMNOJWXQ^_[[[X^^\__]\\ZVVTcca^^\ZZW_a\de^XZSde^ab[_aZbc\TUPZZW]][\\Z__]cca__]aa^VXWUZ[PUWNSUcdfiik]]]cab[ZWVWSccaddd\[_WV]TSZSQVTSW]^bvwycdfqrttwvwyx›œ˜šœ©ª°ÉÉÓ××á¾¾É[[hxx…ˆˆ•””‰ˆ½½¿ÝÝߢ¢¤°°²¾¾ÀÌÌÎÂÂÅËËÍÒÒÔ¦¦©––˜½½¿ÆÆÈÕÕ×ÚÚÜææéææéÛÛÛ¿¿ÁÍÌÕ¿¾ÇÍÌÓÈÇΣŸª·¶¿ÀÁÇÝãèáïíèúøèýøåþøæÿùåþøäý÷äý÷ãûöãûöãûöãûöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßôñßôñÞóðßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïXXXaa^XXVTTQOPLOPLWXQZ[V[\Weec__]bb_[[X__]XXVUVQbc\de^STMXZSde^cd]]^WUVOWXTSSP]][XXV]][XXV[[XTVSNSTGLMEIJ_acaac]]]b_a_^\VVTcca^^^VVXTTVWWZZZ\WWWZ\[fih_ba_bafihqsrŽ‚…‹Œ‘ÅÆÌÖ×ÝÒÓÙ¥¥±vveeq‡‡“‡†Ž“âá囚ž´´·ÅÅÇÍÍÏÈÈËÈÈËÒÒÔÍÍÏææéÒÒÔÍÍÏÌÌÎßßâååèññóäääÇÇÉÆÅÌÐÏÖÈÇÎÄÂǽ¹Á­¬³ÅÆÉÎÔÖßëëé÷ôêûøêýùéþùåþøäý÷äý÷ãûöãûöãûöåúöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßóóßóóÞòòßôñßôñÞóðÞóðÝòïÝññÝññÝññUUS\]X_a\UVQQSNIJFOPL\]XZ[V]^Z^_[]^Z]^ZWXTZ[VXZUab[de^[\UMNG^_XWXQZ[TZ[TVWSWXT_a\XZUab]QSNXZU\\ZNPMVXWGIHXXXeee^^\aa^ccaUUSeecddbZZZSSS___[[[OOO[[[hhhXXVddbjjhyyw‡‡‡€€‚Œ‹¿¾ÅÒÒÔÈÈ˶´¹£¢¦~}„^]fvs€ˆ†“Ÿž¨“‘˜ž¢ÞÞáÒÒÔÌÌÌÇÇÉÅÅÇßßâÉÉÌÖÖÙÐÐÓÒÒÔÙÙÛÞÞÞêêêêêêÕÕÕÅÅÇÈÈË××ÚÀÀÂÀÀ··¹½¾ÀÉÎÏËÒÒÙßÝìöòìøôêýùéþùèýöåúóéþ÷åúóäùòäùôãööä÷÷ä÷ôåøöãöòåøôåøôâôñâôñâôñâôòáóñáóóáòöáòöáòöáóñáóðáóñáóñßòòßñôßñôßñôOPLUVQ]^ZZ[VHIEEFAMNIXZUTUP]^Z^_[WXT^_[XZUTUP]^Z\]V]^WXZSEF?WXQUVOZ[TZ[TXZU]^Z[\WZ[V^_[STOQSN]^ZSSP\\ZPPNVVTZZWQQOWWU\\ZPPNXXViif^^\LLIUUSWWUSSP^^^cca_a\cd_rsowxsttrqqs{z—–›¤¤¦‚‚‚ŸŸŸ¹¹»˜—œ€‰dbp}zˆ‡…‘Œ•–•œ©¨¬ÂÂÅÀÀÀÇÇÉÐÐÓÖÖÙºº½ÏÏÒÛÛÝÈÈËÉÉÌÝÝÝ×××ßßßÖÖÖÄÄÄÍÍÍÌÌÌÅÅÅÁÁÁÇÇǰ²±ÅÇÆÅÉÈÂÇÆìñðïøôìþúêÿúéþ÷éþ÷åúöèýøåúóâ÷òæù÷åøøãöóâôòæùöãöòâöïåøôâôñâôòáóñßòòáóóáòöáòøáòöáóñáóñáóñáóóßòòßñôßñ÷ßñ÷IJFQSN^_[^_[JLGBD?GHDTUPSTO\]X]^ZVWS^_[XZUTUP]^ZZ[T[\U]^WGHAVWPVWP[\UXZSXZS^_XZ[TXZS\]VNOHOPI^_[]^ZZ[VQSNSTO^_[QSNSTOXZUQSNWXTjkfXZUMNIQSNZ[V[[X__]eec_a\de^fhadeappmlllihl~}rrp€€~¥¥¥‰ˆ£¢©ecpb_lljw´³½´³ºœ¡±±³––˜´´·ÕÕ×ÛÛÝÜÜÞÍÍÏÖÖÙÈÈËÐÐÓÓÓÓÐÐÐÜÜÜÓÓÓÍÍÍÔÔÔÆÆÆÈÈÈÆÆÆ¾¾¾‹Œ¹»ºÎÓÒÁÆÅ×ÜÛôþúìþøèûôåøôåøôéûùåøöä÷ôæù÷âôòãöóåøôæùöãöòåøôåøôâôñä÷ôãöóâôôâôôáóóáòöáòöáòöáóñáóñáóóáóóßòòßñôßñôßñôHIETUPbc^^_[MNI>?:EFA[\WXZU\]X]^Z\]X]^ZWXTZ[VXZU^_X^_Xbc\STM[\U[\U]^WVWPZ[T]^WZ[TUVO[\UHIBQSL_aZUVQWXTWXTQSN\]XOPLSTO]^ZPQM\]XijeXZUVWSUVQbc^^_[ccaab]fhacd]bc\de^efb___aacqqsmmmhheqqo{{~ÂÁÆ{z„\[d[Zcdcjjimˆ‡Œ¨¨ª••—««­ËËÍÇÇÉßßâÔÔÖÕÕ×ÕÕ×ÓÓÕÙÙÙÙÙÙßßßáááÔÔÔÍÍÍÕÕÕÌÌ̹¹¹ÉÉÌœŸ²³¶³¸¹ÐÕÖÌÐÒéððíûùëûúìýûéùúéùýéøÿè÷ÿåôûå÷úä÷÷ä÷÷ãöóä÷ôâôòâôñä÷ôä÷ôãööãööâôôáóóáóóáóóáóóáóóáóóáóóáóóßòòßòòßòòßñôIJFIJFZ[V\]XLMH9:6BD?]^ZVWSUVQXZU\]X[\WZ[V^_[WXTab[\]V]^WXZSNOHTUNXZSXZSZ[Q]^UbcZ\]T\]TTULWXOZ[TSTMXZS]^WLMFZ[T[\U_aZbc\OPI]^Wde^bc\^_XWXQab[]^Z[\W^_[hibde\abX_aZ]^Zbb_VVXjjljjh_a\jkfccahhj¦¥ªÌËÏŽ”•”›zy~~‚ªª¬¥¥¨bbd­­°¾¾À¤¤¦¾¾ÀÀÀÂÍÍÏÓÓÕÒÒÔÜÜÜåååßßßâââÜÜÜÔÔÔÈÈÈÁÁÁÆÆÈÅÄÈž¢°±´­²´ÂÇÉÛßââèêêôøéöúÕâé·ÂÌ—£±—¢´š£¹¡«¾·ÅÓ°À˺ÌÓÍÞäâó÷áóóÝðíä÷ôÝððáóóáóóßòòáóóáóóáóóáóóáóóáóóáóóáóóáóóáóóáóóáóóLMHLMH\]X^_[QSN?@;EFA[\WOPLQSNZ[VVWSZ[VZ[VZ[VUVQ\]V[\U]^W\]VJLEPQJUVOUVOWXO\]TabXZ[QQSITULXZP[\SOPIWXQbc\UVOTUNWXQ[\U[\UNOHde^ab[[\U\]VUVO]^WXZS\]Xcd]Z[Q]^Ucd[]^UZ[T__]ZZZfffbb_Z[V_a\bb____‹‹žž¡¶´¹²±¶‰ˆ~~€œœž¸¸ºkkm‚‚…‘œœž¨¨ª´´·²²´½½¿ÍÍÏÐÐÐÚÚÚßßßéééæææÛÛÛÌÌ̸¸ºÎÍÒ¿¾Â¡¢¥©ª­«°²´¹»ÎÓÕáæëÏÖÝÇÎ×­´¿Ÿ¥¶¬±Æ¢»„‡¤„‹¦„¥€Ÿ‹›¨—¨²¨¹ÀÆ×ÝÜíñÞðóäöùâó÷ßñôÞññáóóáóóáóñáóñáòöáòöáòöáóóáóóáóóáóñáóñVWSQSN[\WZ[V[\WGHDHIEXZUNOJSTOZ[VXZUZ[VVWSXZUOPLWXQXZSWXQXZSGHAMNGPQJQSLSTJ[\S_aWUVMMNEQSIUVMZ[Q\]VQSLXZSXZSVWPZ[TXZSUVOOPIde^^_XWXQ\]VTUN[\UUVOZ[VZ[T]^U_bU^aTbcZUVOaa^\\\bbb\\ZXZUbc^iif^^^iiikkk´´·¡¡£‡‡‰œœž¥¥¨jjl‡‡‰ÄÄÆ””–††ˆ••—¹¹»¹¹»„‘‘‘ÒÒÒðððÔÔÔÙÙÙåååÙÙÙÆÆÈÂÁÆÎÍÔš›¡¬­³°³¹¥©¯»¿ÅÞâèëñóÖÜáÇÌÖ¸½Ëßãø±³ÎŽ­„‹¨~‹¢z‰›}ŒŽŸŽž­¡­¢²¿¾ÎÙÙêñãôúáòöÝððáóóáóñáóñáóñáòöáòøáòöáóóáóóáóñáóñáóðWXTTUP]^Z\]Xab]MNIJLGWXTIJFPQMNOJ[\W[\WPQMZ[VIJFUVOVWPOPIPQMDE@IJFNOJNOJPQJZ[Q^_VSTJOPGOPGNOFXZP[\UNOHUVOVWPIJDSTMWXQUVOPQJ\]V_aZZ[T^_XUVO[\UTUP\]XZ[V_aWcd[WXO\]Tab]^^\]][aa^\]X^_[dealmieecbbbTTQddb———¢¢¢}}}«««›››SSUyy{»»¾……‡ppr€€‚¾¾À˜˜›†††ppp¶¶¶äääíííæææâââÝÝÝÏÏÏÄÂÇÄÂÇÁÂÆŽ“±²¶—˜œ¨©¬ÒÖÙèìïÓ×Ú»¿Ç½Á͸»Ïœž·€‚Ÿ…¢}†ž{ˆ{ˆy†›x…š}‰žˆ•ª•£´¡¯½ËÜãáòøáòöáóóáóñáóðáóðáóóáòöáòöáóóáóóáóñáóñáóñSTOVWSWXTUVQUVQVWSPQMXZUGHDJLGOPLab]LMH[\WPQMIJFQSNMNISTOTTQIIGNNLLLLMMJSTOSTMUVOUVOQSLWXQSTMVWPVWPPQJOPISTMGHAQSLPQJSTMUVMUVM\]V^_XXZUUVQUVQMMJTTQZ[V]^W_aZab[[\UXZU^^\[[X\\Zdeade^ab[lmiffd__]UVQZ[Tjkf}~yool‚‚€iifXXXlll¡¡¡ŒŒŒ•••žžž~~~hhhddb““¸¸¶ÎÎÌååãÕÕÓÖÖÔ¯¯¬ÇÇǺº½ÐÐÓ±±³©©«ŸŸ¢Ÿ¥¦©ÍÎÒæèí¯¯¸©«¸›¯Ž¥†‡Ÿ„†¡ˆ¤”˜­Ÿ¤»¤©À“—¯‰Ž¨„t{•…¢¤²ÂÕåðáòøÞòòßôðßôíãøñâôñãóòãóòãóôâòóâòöâòöâòöJLGPQMVWSVWS[\WXZUNOJSTOGHDIJFUVQ_a\LMHWXTNOJEFAQSNLMHNNLUUSLLLLLLGGIJJJOPLPQJTUNTUNSTMMNGZ[T[\UVWPPQJOPISTMNOHLMFSTMOPIUVMUVMXZS]^WVWSTUPOOMHHFPPNXXV]^Zab[cd]^_[XXV]][^^\__]^_[^_XUVO^_[XXVTUPQSLVWNcd]mohbc^xytffd\\Z___qqq‡‡‡†††vvvmmm\\\^^\qrm¦¨£‰‹†×ÙÔ«¬¨ÄÅÀ‹ÌÌÌ···ÎÎÎÐÐÐÛÛÛ½½½ºººªª¬ÝÜãÒÐÚ¾¾É¬«»”–¨‡ˆˆ‰¢‰‹£…‡Ÿ†ˆ¡“«›¶¢¤½–˜±Ž©„ˆŸy‚˜‡•¦£±¿ÕæíÞðóÛðìáöïßôíâôñãóòãóòãóôâòóâòöâñøâñøFGBNOJTUPVWSVWSTUPJLGOPLPQMLMHZ[VTUPJLGVWSVWSNOJOPLMNIMMJSSPPPPGGG@@BGGGIJFQSLMNGUVONOHWXQ]^W^_XVWPPQJOPISTMUVOHIBOPINOHUVMUVMVWN[\UQSLUVQQSNPQMOOMVVTWXTZ[Tef_deaZZW^^\[[Xaa^XZU^_X[\U]^ZPPNJLGUVO\]Tab[bc\TUPefb[[XQQO\\Z__]eeeqqqxxxiiiqqsVVV\\Zffdlljyyw¶¶³{{y——•rrp´´´³³³ÆÆÆÁÁÁÈÈȬ¬¬½½½»»¾âáèÇÅÒÍÌÜ–•¨‘“©€˜{{—„„¢€‚Ÿwy–~€›‘ª£¦»²¶ÉŸ£´–©€ˆœ{†˜‚¡¬»ÆÚëñæùùãøôáöñâôòãóòãóôãóôâòóâòöâòöâòö@@>FFDJJHJJHVVTPPNBB@DE@QSNJLG[\WTUPJLGTUPUVQIJFIJFPQMNNLOOMSSSEEE::=EEEHIEHIEQSNQSNNOJQSNTUPZ[VVWSPQMOPLSTOXZUIJFJLGNOHJLBTULXZP]^WNOHSTOMNIJLGPPNPPNOPLPQJ]^Wbc^XXVVVT\\ZccaPQMVWPWXQWXTJJHGHDVWP]^U^_XXZSPQMcd_bb_]][TTQ\\Z___hhh[[[TTV^^aLLNNNNbb_ddbiif‚‚€eecmmk]][ŸŸŸ³³³ººº¾¾¾………{{{žžžÂÂÅÙ×ÜÆÅÎÆÆÒ°¯¿Ö×ì¿ÀÙ••±††¤wx—xy˜}œ€‚›‹Ž£”—©¢°šŸ­•©t‘w“Œ›¥ÏÞæÜíóßñôä÷÷ãóôãóôãóôãóôâòóâòóâòóâòö>>>AAAMMMFFFHHHJJJAAA@@>PQMPQMXZUMNI@A=HIENOJEFAGHDFGBFFDGGENNNAAA99;>>>DDA@@>LLIMMJLLIJJHNNLOOMUUSMMJIIGPPN]][SSPJJHMNISTJWXO^_X^_XPQMEFAHHFIIGLLIPPNVWSSTM^_X]^ZSSPTTQUUS]][UVQUVOZ[TUVQHHFMNIWXQ_aWab[]^WUVQ\]XZZWPPNUVQXXVQQO[[[UUUMMOONSGGIPPPZZZZZZ\\\TTT[[[\\\iii‹‹‹Â–––°°°sss€€€ˆˆˆžžž½½ºÉÉÇÀÁÅ••žÅÇÖÐÒæ˜š²‡‡¥{}œxy˜xz•}—‚†š˜œ­šžª¨­»¢ª½‹“¦r}Žsލ·ÆÐÜíôÛìòãó÷äôöãóôäôöãóôâòóâòóâòó666;;;GGG>>>DDDAAA>>>AAAMMJJLGPQMNOJBD?HIELMHDE@DE@EFAEEBDDASSSFFF88:::=;;;@@>??=IIGGGELLIGGEFFDOOMLLIFFDQQOXXVSSPNNLHIELMFSTJ\]V^_XWXTGHDFFDDDAGGEJJHQSNMNG[\U]^ZSSPOOMVVTXXVUVQPQJVWPLMHIIGSTO^_Xfh^fhabc\VWSQSNSSPXXVNOJTUPWWUPPPQQTGGIHGLA@ENNP[[[UUU___WWWSSS]]]ZZZbbbœœœ~~~jjjlllooo‚‚‚‹‹‹±²­ÇÈά«xy¦ª´}Ž‚—xy‘rty{–{~–wz…˜¢šž¬£¨¶¢¨º˜¬rzlwˆr}ŽŒšª²ÀÎãóþâñøãó÷äôøâòóãóôãóôâòñâòñ>>@::=FFHFFHJJMHHJBBE999MMJIJFGHDDE@BD?FGBLMHGHDBD?FGBFFDBB@TTTJJJ88:99;888777>>>BBBLLLEEEGGGGGGJJJFFFGGGQQQQQQUUUOOODDAMNGPQHVWPVWPWXTIJFLLILLINNLLLIMNIHIB^_Xfhc\\ZTTQWWU[[XZ[VUVOWXQOPLHHFTUPbc\ijahibab[XZUFGBJJHXXVOPLXZUUUSNNNSSUPPSQPUDBGJJMUUWPPS^^aJJMHHJPPSbbd^^acceXX[VVX[[]ddf~~€‚‚…¯¯¯–––£¤¦mot˜z~ˆoq~qs‚ps‡{”{”rv‹tx„‡œ‚†›Ž‘¦—œ±‘¦iq…fo‚s~ˆ“¥—¥·ÄÒâÜëóâñøâòöâòóãóôãóòãóòâóð???>>>IIIGGI??A;;>AADAAAEEBHIEEFA?@;?@;BD?LMHMNIDE@IJFIIGDDAQQQNNN:::;;;777666===AAAJJJNNNMMMNNNGGG>>>JJJPPPMMMVVVLLLFFDGHDMNGUVOVWP]^ZOPLQQOQQOJJHEEBHIEFGBUVQbc^VVTJJHOOMZ[VVWSXZUQSNXZULLI]][^_Xde\cd]\]Vab]NOJNNLSSP\]XXZUXXVJJHQQQPPSUTXLJOFEIIHMNMQZZ\PPSMMOOOQ[[][[]]]___bWWZTTViikŽŽooq‚‚…yy{ˆ‰fhkz~„kotfjrilwoq~vx‡rt„fizwx„…›~•„†žˆ‹£…‰¡vz‰‘¤qypyˆ‘ª˜¥ºÅÔÞÛêñßðóßðñâòóãóòãóòãóò480794BEALNM>?A236687FHE@@>FFDFFD>>;GGEAA?FFDHHFDDALLIJJHJJHVVT]][TTQFFD442997;;9@@>DDALLIJJHBB@BEAEGFILJEFHFGINPO@BAGIFDDAIIGUVQ[\WOPLLMH997???GGEBB@FFDEEB]][[[XQQONNLLMHSTONOJWWUSSPMMMIIIUUSef_de\ab[ef_cd_TUPMMJNNLWWU\\Z[[XTUPMMJNNLUUUSSUDEJEFLFGMVW[MNQIJNIJMUVX[[[QQQUUUVVVOOO]]]eeeeeeefi^_bijlabdcdhopshilefjdekqqzssjjwrq‹‰œ˜—¬‡ˆž„„ŸoqŒcfzw}{”s{‘t{˜~‡¢›¬ÌÙßßìïâðïäôöáñòãööáóóAE:AE=EGBDFE9:=013687ILHEEBLLIGGE886663@@>GGEEEB??=MMJPPNQQOaa^bb_XXVTTQ??=@@>;;9DDAFFDLLIJJHAA?JMIEGFGHJFGIDEGIJMJMLFHEFFFGGGVVTXZUQSNTTQ???;;;FFD@@>FFDNNLiif__]SSPSSPMNIOPLOOMJJHQQQFFFDDFBBBVWPab[ab[TUP\]XVVTMMJMMJSSSWWWPPNXZUIJFNNLNNNOOQFGMDDMGHNTU[NOSEFIEFHVWZSSSMMMTTTXXXQQQVVV[[[WWW^_bUVX^_b]^a]^abcebce]^abcfdei{}‚ffpvv‚Œœ«ª½Œ‰¡‰‰¥ij‚advsx†£¦º{€—tx–t{—€ˆ›¤ÛèêäòñãóôäôöÛííä÷÷BF;=@8>@;>@?78:-/1243BEAMMJOOMFFD220220??=EEBGGE@@>IIGJJHLLIUUSbb_ccaaa^OOMEEB997BB@DDALLIJJHBB@DFB>@??@B?@B:;>@ADNPOILHLLLNNNZZW\]XUVQOOMPPP@@@LLIMMJIIGJJHbb___]TTQLLIUVQMNIOOMNNLNNN===::=???PQMXZS[\WGHD\\ZLLIFFFIIIQQQWWWLLIXZUJLGOOMOOOJJMGHL@AGEFLNOSOPTFGIFGIWZXMMMHHHNNNTTTVVVUUUSSSWWWTUWUVX\]_VWZbce]^a]^abcebcfdeibci^^hhhsllyzy‰‹‰žˆ‰¢qrˆikzšœ©¬°Á–š¯qsrwr{‹v€ˆÅÒÔâðïáñôãó÷åö÷ßðñTWMNQI?A=@BA@AD347243?A>NNLIIG??=774>>;;;9==:JJHGGEHHFHHFQQOJJHQQOSSPXXV]][HHF774AA???=IIGMMJGGE:=9;>=@AD=>@;=?;=?EGFDFBGGGOOOOOMXZUWXTJJHJJJ???LLIHHFAA?GGEZZWTTQJJHJJHHIEHIEHHFGGE@@@;;;88:AAA\]XXZUXZUUUSLLI???IIIGGGJJJQQQQQO_a\QSNQQOSSSFFH@AE;=BBDGGHLPQTMNPMONX[ZJJJEEEIIINNNIIITTTTTTVVVOPSNOQTUWVWZXZ\_acXZ\[\^^_cefjfhmQSXeeoddpxx…†…•‘“¨z}Ž_bomq{ž—˜­~—txqw…w‰Ÿª­Üéëäñøâñøãó÷áñò[^TOSJ8:68:9@AD124364>@=LLIJJHAA?::8HHF;;9??=QQOBB@??=QQOSSPNNLOOMOOMNNLZZWEEB::8EEBEEBFFDLLIPPN9;80219:=46801389;>@?@B?FFFQQQSSPNOJXZUSSP>>>BBBOOMLLIGGEFFDOOMHHFBB@BB@EFA?@;AA?DDADDD???::=EEEPPNPQM[[XAA?>>>:::FFHPPSFFFMMMNNLXZUSTOMMJSSSIIL?@D:;?GHLSTVIJMMONNPOUWTOOONNNFFFMMMHHHQQQOOOQQQLMONOQOPSMNPXZ\]^aVWZPQTVWZVW[^_c]^b[\b_afffpmmyz}‰acp[^feiqmp}‰ˆ˜{zoq‚lq{ipw‡“ÅÏÕáëóÞëòßìñéöúTWMLOGDFA;>=@AD679132@B?LLIQQOGGE774MMJEEBAA?NNLEEBAA?PPNLLIWWULLIFFDIIGVVTAA?442??=BB@IIGJJHTTQ>@=79889;/02124>?A?A@GIFGGGEEEHHFQSN[\W^^\LLLLLLLLIIIGJJHEEBIIGIIGAA?GGE@A=DE@HHF@@>BBBHHHEEGBBBJJHMMJZZWBBB@@@NNPGGIMMODDDAAA>>;NOJXZUMMJPPPIIIBDFBDGNOQZ[]LNMLNMJMIQTPVVVQQQEEELLLHHHNNNSSSVVVPQTOPSPQTFGITUW[\^UVXTUWQSUTUW\]_^_cOPTVW[cdhklrdhpSV^W\^efjss}€€vt…oo{eiqekpv~¶½ÄÜãì¸ÁÌâìòâïóMPFMPHNPL=?>=>@78:8:9LNJGGENNLHHF>>;PPNNNL>>;JJHBB@@@>MMJFFDUUSTTQNNLHHFWWU@@>331;;9DDAQQOIIGUUSFHE;>=89;34789;@AD:=;>@=HHH>>>HHF]^Zab]\\ZZZZLLLLLIMMJHHF@@>DDAEEB774IIG@A=;=8FFDBB@DDDJJJNNPGGGGGELLI[[[EEENNPQQT@?DBBE;;;>>>??=QSN^_[LLIJJJIIIGHJHILMNPUWVNPOHJGEGDMOLSSSVVVLLLOOOMMMJJJWWWWWWVWZMNPIJMIJMPQTPQTZ[]WX[LMONOQ[\^_acUVXUVX^_bbceX]_TX[dehdehdcjvt~wtjirbfibhjjpt£©°¿ÆÐ”žÌÖÜÙãæIMBSVNPSN=?>=>@1249;:HJGMMJFFD??=@@>AA?UUS>>;TTQFFDGGEUUSMMJLLIOOMOOMLLI\\ZEEB663>>;FFD[[XFFDNNLBEA8:92364682369;:HJGILHDDDFFDIJFJLG[\WPQMJJH??=GGETTQJJH886>>;MMJ;;9HHFFGB?@;NNLIIGFFFSSSUUU???GGGMMM^^^JJMIILEDHDBG;:?88:>>>==:HIE^_[GGEFFFHHJBDFFGIGHJSUTOQPGIF@B?ILHGGEXXXWWWVVVSSSHHHXXXUUUQTSQSUGHJMNPMNPNOQXZ\\]_QSUPQTVXWX[Z[]\UWV^a_abd^cdPUVacbbdcbaehfmmlsbah^cdejkilrv{‚‚‡“}„Ž»ÂÉÙãæGH?PQJWXTMMM@@B//1BBBBB@JMH:=8362798>@?TVSFHDTVQDE@MNIVWSOPLNOJJLGMNIHIEQQOOOM9:6FGBVWSab]GHDLMHJJJ>>@224224DDDIII??=DDALLIHHFMNINOJVWP^_XSTMHIEJJHMMJDDA442::8886886EEBNNL@@>EEBTTQAA?LLIXXVIIIOOOEEETTVPPSVUZFEIBAH:9>88:???@@>JJH]][AA????JJMABFFGJHIMFGIXZ\MONILJMOLIIGTTQ^^\MMJTTQPPNNNLTTQSUTQTSNPOLNMILJILJQTS\^][\^UVXUVXVWZ^_b[\^[\^]^a\]__ac\]_^_babd^_c^_c_ac^_bijlhioeiq_dp^co€‡Ž•œ£@A8MNGOPLIIIDDF113:::;;9PSNAD?3644768:9NPO@B>OSJNOJLMHOPLLMHPQMFGBLMHAB>UUS[[XGHD?@;HIBZ[THIBJLGFFH327224BBELLLPPPAA???=??=??=HHFNOJPQM\]VUVONOHJLGPPNNNL;;9442663774GGEPPNBB@AA?QQOIIGEEBPPNSSPWWWIIIGGI??AFEI@?D=;B98=779??ADDDZZWaa^LLL@@BJJM9:>?@DDEHFGJOPSGHJGIHJMLJJHOPLZ[VUVQXZUVWSQSNVVTPSQX[ZWZXLNMHJIFHGJMLUWV\]_TUWQSUTUWZ[]WX[STVXZ\[\^XZ\[\^Z[]^_bQSUVWZ\]_bbbcce_afadlX\fX]hsy€}„‹GH?LMFTUPFFFQQT113111;;9MOJAD@/10/02468JML=?;JMHNOJIJFOPLMNIGHD?@;IJFEFAFFDUUSWXTPQMNOHWXQJLEQSNLLL99;,,/;;;UUUUUSNNL@@>@@>>>>EEBGGELMHVWSNOHGHABD?MMJPPNHHF886220997@@>SSPDDA==:NNLJJHFFDPPNTTQWWUJJJNNNHHJ@@B;:??>BIHM@@B??AMMMZZWZZWQQQ;;>GGI:;?;=@?@DBDGMNPHILGIHHJIMMJNNLUUSZZWVVTUUSPPNTTQQTSWZXVXWOQPHJIGIHGIHOQPXZ\QSUNOQVWZXZ\Z[]PQTWX[XZ\VWZXZ\WX[]^aPQTQSU]^a_acWX[TU[[^fSV^LOW_ej_ejLMDQSLNOJ@@@SSU>>@777;;9LNJFHE236347679LMO>@=MOLPPNIIGOOMEEBBB@AA?FFDDDAMMJVVTVWSFGBFG@VWPQSLVWSFFF447;;;777LLITTQHIEEFADDDAAAGGGIIGFFDTUPQSNMNIMMJUUSMMJPPN==:++)997??=TTQDDA>>;LLILLIIIGNNLPPN\\ZIIGUUULLLWWZMMOFEI87;668==?HHHQQO\\ZJJJMMOHHJ89=9:>@AEHIMIJMEFHADB?A@OOOQQQSSSVVVNNNQQQNNNPPPSUTLNMMONSUTNPOILJHJIMONWX[TUWJLNMNPTUWTUWIJMTUWTUWWX[TUWVWZUVXSTVJLNXZ\WX[OTVIMSPTZQU]OSXZ^aW\^VWNUVOMNIDDDOOQTTVHHH::8>@==?>*+-&(+67:@AD@BAEGFFFF>>>FFFFFFMMMPPPPPPMMJAA?QQOWXTHIEIJDNOHTUNPQMJJHGGGTTTFFDIIGVWSSTO>?:888668>>>AAA>>;HHFPPNSSPSSPMMJNNLQQOIIG774442??=VVTOOMEEBFFDUUSMMJIIGMMJXZUXXVWWULLLTTTLLN--0336113>>@HHHUUS\\ZOOOLLN??A67::;?=>AGHLDEGFGI=?>EGFLLLTTVLLNOOQLLNNNPGGIQQQSUTOQPQTSOQPWZXPSQOQPZ\[VWZUVXGHJLMOPQTXZ\FGIHILPQTQSUTUWWX[STVZ[]MNPPQTMQSPUWJNTBFLLOUVZ_TXZTUWWXOLMFHIE???DDFGGI>>>11/79878:)*-*+/237469468:=;DDD======AAADDD@@@@@@DDDEEBUUSVWS?@;@A:FG@VWP[\WQQO[[[SSPEEBNOJQSNOPI894AAA>>@>>@======JJHPPNJJHIIGMMJHHFNNLOOM@@>AA?BB@UUSVVTNNLHHFSSPIIGMMJJJHUVQSTOLLIQQONNNOOO;;>IIL88:;;>QQQOOM[[X\\\BBEDDF?@D?@D;=@>?BDEGDEG9;:;>=EEGPPSJJMGGIGGIJJMFFHLLNJMLMONQTSPSQSUTSUTUWVTVUOPSNOQEFHIJMIJMPQTBDFFGILMOPQTSTVTUWMNPVWZTUWOTUFMMPVXPTZEHNIMSTUXQTSQTSUVMPQJEFABBB??AEEGBBB886243236(),/0634:67:78:=?>FFH::=::=??AAAD::=::=AAATTQVVTWXTMNIJLEFG@NOHOPLTTQ^^\]][GHDMNIQSLEF?9:6IILGFJ??A::=999HHHMMJGGEGGEJJHGGENNLSSPGGE??=;;9OOMWWUTTQGGEIIGJJHNNLFFDQSNLMHMNILLINNLNNNFFF@@@GGIMMOUUUGGEXXVNNNAAD88:78;9:>?@D@AE:;>>?A?A@@BAEEGNNPLLNFFHEEGGGIEEGEEGFHGMONOQPSUTTVUQTSVXWOQPTUWNOQEFHEFHBDFMNPHILNOQHILJLNPQTQSUHILPQTWX[MQSAGIMSUQW\IMSMQTTUWTTQVVTJLEIJDHIE??=BBBQQQIII444-/1236+,0/03-/29:>;=??A@JJM447@@B@@B>>@::=::=>>@@@@UUS[\WGHD?@;BD?OPLWXTPPN\\Z\\ZLMHGHDLMHDE@==:LLNMMOAAD==?777AAAJJHLLIHHFBB@>>;@@>@@>BB@>>>999HHHPPPMMJFFDJJHFFDFFDLLIMNINOJJJHIIGMMJ[[[XXXUUULLNPPSQQQDDAUUSPPP99;44778;=>AIJNIJM9:=?@BDEGBDFBBEEEGFFHBBBBBBEEGFFHAADEGFNPONPOSUTPSQILJVXWVXWUVXOPSJLNJLNEFHJLNFGIFGIFGIHILLMOPQTHILMNPWX[GLM=BEJPSOUWJOQLPQPSQNPMTTQNOJOPLPQMGHDDE@GGEBBE87;:;A01778;013124468:;>>?AEEG779779AADIIL99;336::=HHHZZWUUSEEB>>;FFDLLI[[XPPNZZZ\\\PPNBB@MMJBB@BBBDFEILJ;>=FHG=?>8:9MONFHGLNM@B?9;8=?;?A>;>=78:348=>AGHJHJIILHLNIJMIHJGFHGHJINPOFHGFHGFHGLMO?@B:;>ABEIJMEGF?A>TVSOQP@AD89;/039:>FGIUWV=?>;=?:;>?@D=>AEFHSUTOQNEGD=?>@AD?@BLNMNPOPSQQTSQTSJMLNPOX[ZTUWPQTIJMNOQJLNGHJGHJIJMDFEGIHGIHMONFHGLNMVXWMNPINOHMNMQSLPQHMNINOMQPQTSPPNMMJLMHDE>;=8AA?>>@32911:/06;=@6796879;:9:=:;>>>@224779??A==?224//1668===IIGVVTNNL>>;EEBPPNTTQZZZXXX\\\IIIAAAGGGFFF@@@?A@BEDDFEBED:=;8:9JMLEGFILJ>@?362362:=;89;46923967=@AEDFEEGDGIEFHEEGFDFEJLNNOQDEGABEFGIQSUDEG9:=BDFABEDFE@B?OQNTVUIJMABE2379:>EFHVXWEGF;=?78;:;?>?BIJMTVSTVQJMHBEADEG?@DGHJHJILNMQTSMONHJILNMTVUWX[OPSIJMMNPPQTJLNEFHABEGIHHJINPOLNMJMLSUTTVUMONFJLEIJINOHMNEIJGLMINOLPQIIGQQOTUPFG@9:6??===?329,,6-/4?@D?@B243=?>;=?>?A?@D12667:78;-/2+,0126;=?>>>HHFUUSQQOAA?AA?JJHUUSUUUZZZWWWPPP@@@JJJEEEEEEADB@BAHJIADB9;:9;:HJIEGFMONDFE9;8796=?>9:=46912889??@D=?>;>:?A=BEAFHGILJGHJJLN?@B?@B?@BQSUNOQLMO>?AEFHILJ?A>NPMSUTHIL@AD:;?ABFGHJVXWSUT>?A78;89=469GHJQTPWZUOQMILHEFH>?BJLNHILFGIGHJEFHBDFFGILMONOQIJMGHJEFHJLNJLNHILEFHEGFFHGJMLEGFBEDMONQTSNPOHMNGLMLPQJOPBGHDHIGLMINOQQOUUSUVQGHA=>9BB@AAD98?//8+,2>?BEFH687ADB:;>:;>>?B126:;?:;?237014348:;>???MMJLLIDDA>>;FFDHHFQQOWWWUUUZZZPPPEEEIIINNNGGG@BA8:9=?>:=;7989;:FHGDFEHJIDFE=?;9;8DFE>?A469/0667=>?B>@?=?;FHDFHEFHGFHG>?AFGI?@BBDF;=?EFH;=?9:=78:?@B=?>=?>PSQLNM=>@67:67:ABFDEGJML\^]GHJ>?B89=:;?MNPPSOTVQOQMILHGHJABFHILGHJEFHEFH?@B?@BBDFFGIHILMNPNOQ?@BIJMJLNIJMEFHFHGNPOJMLFHGILJMONVXWLNMEIJDHIHMNGLM?DEAFGDHIFJLSSPWWUWXTPQJ=>9??=DDFA@GEEN12878;347798@BA@AD4687;>&*037=14:-17*-3*-3-/2:::NNLQQOIIG??=AA?GGELLINNNUUUWWWNNNAAAHHHQQQGGGEGF?A@9;:ADB8:99;:DFE@BAEGFBED@B?=?;GIH9:=126-/478>;=@ADB>@=BE@?A>:=;798>?A;=?67978:67989;78:3479:>:;?9:=>?AGHJPQTFGJ46989=?@DEFHEGF\^]LMO=>A12667:FGIQTPX[V^a\JMIHIL;=@?@D>?B?@D?@D;=@:;?@AEHIMGHJ?@BJLN9:=ABELMODEG=>@HJIOQPJMLFHGFHGEGFNPOHJIAFG@EFDHIAFG>BD;@ABGHGLMOOMUUSUVQOPI894886==?>=D88A/0689=6799;:ADB>?A12637=$(-,06(+1*-3(+1*-3014;;;LLINNLHHF@@>==:??=HHFJJJUUUTTTQQQ===GGGMMMIII@BA=?>9;:HJI?A@>@?DFEBEDADBBEDEGDGIFILJ;=?46912834:78;>@?>@=GIEEGDBEDADB>?A9:=12434767989;89;67:78>;=B89=89;DEGNOSDEJ12878;=>AABEDFE[]\PQTBDG9:>FGJMNPSUQWZU]_[PSOLMO?@D;=@:;??@D>?B78;9:>ABFIJNMNPGHJPQT@ADGHJIJMGHJGHJPSQOQPNPOEGFGIHEGFMONMONFJLDHIFJLDHI;@A;@ABGHEIJSSPUUSPQMGHA340997;;>218++4,-378;679364>@?>?A469-17&*2/2:,08%)1%)1*-6239PPPQQOBB@442==:??=;;9==:IIIOOOUUUSSS;;;AAAIIIDDD@BA=?>>@?JMLEGF?A@?A@?A@9;:?A@GIFLNJILJ;=?469128/060149;::=9FHDBEA=?>8:99:=67901334746878:78:46934:89?46967:HIMIJN?@F67=34889=?@BDFESUTPQTDEH>?BGHLIJMOQNSUPZ\WUWTOPS?@D9:@9:@>?E:;A78>89?=>D@AEABEABENOQEFHEFHFGIJLNLMOGIHGIHMONJMLGIHADBFHGHJIBGH?DE@EF=AB9>?;@ABGHBGHNNLQSNOPIFG@:;7::8779,+2%&,,-3469124687>?A;=?014),4#&/&*2"%-"%-#&,*-3348DFELLIFFD??=886DDALLIGGEBBBNNNPPNTTQ;;9IIG@@@>>>9;:@BAGIHPSQOQPEGFDFE?A@=?>BEDLNJQTPGIH9:=126-/467=237:=;=?;@B?=?;9;:78:89=67:01434812634834812622;33=12878;IJNNOSDEJ78>12889==>@ABESTVVWZJLNFGJNOSHILILHJMHQTOTVSMON;=?9:>67=:;A9:@12878>>?EABH>?B?@BHILABE89;?@BJLNIJMFHGJMLLNMQTSNPOADBFHGIJMDHI?DE?DE;@A7;=;@ABGH@EFPQMMNGOPISTMMNIBBB=;@43:)*0()/78;3474689:=78;/06**6%%1$$-%%/()/126236013>@?BED@BA9;:;>=ADBFHGLNMPPPHHFQSNQSNHIELMHHHFBBB78:@ADFHEMOLLNJJMIIJM@AD>?ADFEOQNNPMADB78:34:,,612812689;9;::=;89;78;78>14:14=03;/2=-1;69A26>03;009009/0678;GHJJLO@AG34:1289:@?@D=>AFGJVWZEFHEFH@@BLLNFFFIIGUUSUUSNNLGGGEFH89=34:67=11:88A66?88A?@DEFHHILBDF=>@=>@GHJEFHEFHBDFIJMNOQGHJGHJEFHHIL:;?=>A>?B:;?9:>9:>=>A:;?PQJIJDZ[TMNIDDA===76:218*+1,-3:;?236-/1348128((1))4%%2%%1&&0&(--/2468687?A@:=;798798?A@?A@BEDADB???GGGJLGOPI892>?:???;;>89=ABEFHENPLQTOGIFFGIFGJBDFABEGIHNPMJML=>@239,,634:67=9:>236?@B?@D;=B46;37?,0:+-:02?13@79F14?,08--922;017237:;>QSVFGM67=34:78>EFL=>DBDGNOSGHJ>?A??ALLNHHHFFFSSPWWUPQMEEBNOQ?@D34:239//866?11=>>G?@DDEGGHJ@AD:;>=>@DEGDEG>?A=>@HILNOQMNPFGIABEGHJDEH@AE;=@78;=>A=>A>?B=>AQSLGHAWXQOPLBB@III649107+,2128>?B013+,/126/06%%/&&2$$1%%1))2%&,*+/9:=>@?>@?9;:364243:=;BED>@?>@?GGIGGGNNLLMHAB>IIG;;;==?9:>>?A>@=DFASUP@B?;=?@AE@AD9:=:=;GIFNPO?@B017//834:89?=>A89;>?A89=34:34:26>+/9*,9/1>13@79F14?,0822>//8,-3348?@BOPT@AG23923967=DEJ;=BABFMNQHIL;=?JJMIILFFFHHHVVTTTQMNIHHFX[ZWX\89=67=34:66?11:88A=>A@AEABF:;?78;;=@?@DABF?@B>?AHILNOQMNPFGIABEGHJ?@D9:>67:469BDGEFIBDGDEHLMFQSLTUNNOJMMJ@@@327/-4()/128=>A)*,*+-/03,-3$$-%%1$$1&&2**3#$*&(+;=?BEDEGF679/02679679:;>ABE@ADDDFDDFNNLPPNOOMMMJJJMAAD>?BDEG>@=>@;NPL:=9124014@AD>?A:=;BEALNM=>@-/400967=23934812478:78;67=34:/2:-1;,/;+-:-0=68E26@03;11=11:,-3014FGISTWIJP67=-/467==>D9:@ABFQSVIJM=>@>>@@@BEEEFFFTTQVVTOPLFFDZ\[abdABF237/0612899B67=BDIEFIEFI=>A469:;?;=@@AE?@B=>@DEGHILGHJGHJEFHHILGHL=>A469126>?BBDG@AE?@DSTMIJDQSLVWSEEB@@@98=/-4()/128;=@+,/*+-)*-#$*$$-%%1##0$$0&&0&(-)*-BDFILJ236/03,-1348;=@67:78;34898===?GGGLLLAAA???336-,1+,0236AD@HJFTVQGIF124/03=>@>?AADBEGDBED89;,-3++412846;78;01378:89=89?78>,08(+6-0=02?+-:+-:+/9+/7--9,,6,-3469LMOLMPNOU:;A/0646;89?9:@@AEIJN@AD9:=AAD==?:::AAATTQ[[XLMHLLIZ\[TUWMNP=>A126/06*+19:@;=B;=B>?E46;67==>D?@F>?B;=?;=?BDFEFHIJMIJMHILFGIDEGEFH679124?@BHILHILDEG?@9@A:PQJUVQTTQFFF438(&-()/78>BDG/02)*,)*-#$*%%/##/""/$$0**3()/014GHJTUW89=/03+,0-/2/03014:;?237,+0;:?BBEHHHEEE@@B76:0/34699:=:=9?A=OQMLNJ:;>78;89;;=?>@?=?;>@?78:-/4,,646;46;469,-089;67:128-/4+/7),7,/;,/;*,9*,9*-8*-6--9,,6&(-9:>JLNJLOQSXLMS0172399:@46;BDGDEH>?A;=?HHJ99;888>>>MMJOOMIJFMNIPSOTVUUVXNOQ:;?014/0646;89?67=78>34:01789?;=B:;A9:>468=>@EFHGHJGHJEFHBDFDEGABE9:=89;=>@DEGEFH>?A:;4>?8PQJWXTMMJBBB327%$+*+1?@FJLO347,-0,-1)*0++4((3$$1**666?$%+126BDFSTV:;?-/4,-3+,2239-/4017)*00/698=HHJHHHEEE??A98=/-4:;?;=?8:79;7NPLJMI9:=67:89;@AD@BA9;88:9679/06--746;128126,-078:4699:@ABH+/7),7,/;(*7)+8)+8),7),4))4009+,278;BDFFGJFGM:;A9:@01723934:>?B@AE;=?:;>>>@::=>>>===IIGOOMSTOQSNLNJQTSNPOIJM469-/2126;=B:;A66?33=22;11:77@;;E;=B@AE9:=;=?@AD?@BDEGGHJIJMHJI=?>687798=?>ADBFHGADB>?8:;4IJDTUPIIGHHH:9>&%,+,2DEJQSV78:124237/0622;%%1""/**699B()/78;?@BQSU9:>+,2/06,-3,-39:@89?67=43::9>AADHHHBBB::=76:+*189=78:;>::=8QTOEGD-/1+,0236>?A>@?241364468017--7017,-3014/0223678;78>34:*-6*-8+-:$&3(*7(*7(+6(+3++7))2,-39:>GHJIJNOPVQSX@AG017*+146;;=@?@D89;89;??A==?777;;;FFDOOMTUPPQMLNJSUQLNMGHJ/03-/2+,0;=B??H66?22;33=33=22;33=67=78;4689:=9:=@ADEFHHILIJMDFE4763648:9@BA@BAFHGHJIlibwebp-0.4.0/ltmain.sh0000644000014400001440000105204012255206711011672 0ustar # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 libwebp-0.4.0/Makefile.am0000644000014400001440000000012312255002107012071 0ustar ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src examples man EXTRA_DIST = COPYING autogen.sh