diff options
author | Twinaphex | 2019-05-14 11:44:06 +0200 |
---|---|---|
committer | GitHub | 2019-05-14 11:44:06 +0200 |
commit | 80209d1715398a16b6ace1c2e4cd0aab5c00248d (patch) | |
tree | b7f82140860acabb2d0e3a5216f78bf98691c267 /deps/flac-1.3.2 | |
parent | 5ffd1f23eb970679dfe8b540bc3df8e776dc9e17 (diff) | |
parent | ce188d4d7f3b9ad04867c49b424e8497c2ade92b (diff) | |
download | pcsx_rearmed-80209d1715398a16b6ace1c2e4cd0aab5c00248d.tar.gz pcsx_rearmed-80209d1715398a16b6ace1c2e4cd0aab5c00248d.tar.bz2 pcsx_rearmed-80209d1715398a16b6ace1c2e4cd0aab5c00248d.zip |
Merge pull request #280 from aliaspider/master
add CHD support.
Diffstat (limited to 'deps/flac-1.3.2')
172 files changed, 60867 insertions, 0 deletions
diff --git a/deps/flac-1.3.2/include/FLAC++/Makefile.am b/deps/flac-1.3.2/include/FLAC++/Makefile.am new file mode 100644 index 0000000..118361e --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/Makefile.am @@ -0,0 +1,39 @@ +# libFLAC++ - Free Lossless Audio Codec library +# Copyright (C) 2002-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +flaccppincludedir = $(includedir)/FLAC++ +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +flaccppinclude_HEADERS = \ + all.h \ + decoder.h \ + encoder.h \ + export.h \ + metadata.h diff --git a/deps/flac-1.3.2/include/FLAC++/Makefile.in b/deps/flac-1.3.2/include/FLAC++/Makefile.in new file mode 100644 index 0000000..6ce6e19 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/Makefile.in @@ -0,0 +1,640 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC++ - Free Lossless Audio Codec library +# Copyright (C) 2002-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/FLAC++ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(flaccppinclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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)$(flaccppincludedir)" +HEADERS = $(flaccppinclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +flaccppincludedir = $(includedir)/FLAC++ +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +flaccppinclude_HEADERS = \ + all.h \ + decoder.h \ + encoder.h \ + export.h \ + metadata.h + +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 include/FLAC++/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/FLAC++/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-flaccppincludeHEADERS: $(flaccppinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(flaccppinclude_HEADERS)'; test -n "$(flaccppincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(flaccppincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(flaccppincludedir)" || exit 1; \ + fi; \ + 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)$(flaccppincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(flaccppincludedir)" || exit $$?; \ + done + +uninstall-flaccppincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(flaccppinclude_HEADERS)'; test -n "$(flaccppincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(flaccppincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(flaccppincludedir)"; 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 distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-flaccppincludeHEADERS + +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 -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-flaccppincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + 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-flaccppincludeHEADERS \ + 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-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-flaccppincludeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/include/FLAC++/all.h b/deps/flac-1.3.2/include/FLAC++/all.h new file mode 100644 index 0000000..b679d0f --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/all.h @@ -0,0 +1,49 @@ +/* libFLAC++ - Free Lossless Audio Codec library + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLACPP__ALL_H +#define FLACPP__ALL_H + +#include "export.h" + +#include "encoder.h" +#include "decoder.h" +#include "metadata.h" + +/** \defgroup flacpp FLAC C++ API + * + * The FLAC C++ API is the interface to libFLAC++, a set of classes + * that encapsulate the encoders, decoders, and metadata interfaces + * in libFLAC. + */ + +#endif diff --git a/deps/flac-1.3.2/include/FLAC++/decoder.h b/deps/flac-1.3.2/include/FLAC++/decoder.h new file mode 100644 index 0000000..0b93906 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/decoder.h @@ -0,0 +1,248 @@ +/* libFLAC++ - Free Lossless Audio Codec library + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLACPP__DECODER_H +#define FLACPP__DECODER_H + +#include "export.h" + +#include <string> +#include "FLAC/stream_decoder.h" + + +/** \file include/FLAC++/decoder.h + * + * \brief + * This module contains the classes which implement the various + * decoders. + * + * See the detailed documentation in the + * \link flacpp_decoder decoder \endlink module. + */ + +/** \defgroup flacpp_decoder FLAC++/decoder.h: decoder classes + * \ingroup flacpp + * + * \brief + * This module describes the decoder layers provided by libFLAC++. + * + * The libFLAC++ decoder classes are object wrappers around their + * counterparts in libFLAC. All decoding layers available in + * libFLAC are also provided here. The interface is very similar; + * make sure to read the \link flac_decoder libFLAC decoder module \endlink. + * + * There are only two significant differences here. First, instead of + * passing in C function pointers for callbacks, you inherit from the + * decoder class and provide implementations for the callbacks in your + * derived class; because of this there is no need for a 'client_data' + * property. + * + * Second, there are two stream decoder classes. FLAC::Decoder::Stream + * is used for the same cases that FLAC__stream_decoder_init_stream() / + * FLAC__stream_decoder_init_ogg_stream() are used, and FLAC::Decoder::File + * is used for the same cases that + * FLAC__stream_decoder_init_FILE() and FLAC__stream_decoder_init_file() / + * FLAC__stream_decoder_init_ogg_FILE() and FLAC__stream_decoder_init_ogg_file() + * are used. + */ + +namespace FLAC { + namespace Decoder { + + /** \ingroup flacpp_decoder + * \brief + * This class wraps the ::FLAC__StreamDecoder. If you are + * decoding from a file, FLAC::Decoder::File may be more + * convenient. + * + * The usage of this class is similar to FLAC__StreamDecoder, + * except instead of providing callbacks to + * FLAC__stream_decoder_init*_stream(), you will inherit from this + * class and override the virtual callback functions with your + * own implementations, then call init() or init_ogg(). The rest + * of the calls work the same as in the C layer. + * + * Only the read, write, and error callbacks are mandatory. The + * others are optional; this class provides default + * implementations that do nothing. In order for seeking to work + * you must overide seek_callback(), tell_callback(), + * length_callback(), and eof_callback(). + */ + class FLACPP_API Stream { + public: + /** This class is a wrapper around FLAC__StreamDecoderState. + */ + class FLACPP_API State { + public: + inline State(::FLAC__StreamDecoderState state): state_(state) { } + inline operator ::FLAC__StreamDecoderState() const { return state_; } + inline const char *as_cstring() const { return ::FLAC__StreamDecoderStateString[state_]; } + inline const char *resolved_as_cstring(const Stream &decoder) const { return ::FLAC__stream_decoder_get_resolved_state_string(decoder.decoder_); } + protected: + ::FLAC__StreamDecoderState state_; + }; + + Stream(); + virtual ~Stream(); + + //@{ + /** Call after construction to check the that the object was created + * successfully. If not, use get_state() to find out why not. + */ + virtual bool is_valid() const; + inline operator bool() const { return is_valid(); } ///< See is_valid() + //@} + + virtual bool set_ogg_serial_number(long value); ///< See FLAC__stream_decoder_set_ogg_serial_number() + virtual bool set_md5_checking(bool value); ///< See FLAC__stream_decoder_set_md5_checking() + virtual bool set_metadata_respond(::FLAC__MetadataType type); ///< See FLAC__stream_decoder_set_metadata_respond() + virtual bool set_metadata_respond_application(const FLAC__byte id[4]); ///< See FLAC__stream_decoder_set_metadata_respond_application() + virtual bool set_metadata_respond_all(); ///< See FLAC__stream_decoder_set_metadata_respond_all() + virtual bool set_metadata_ignore(::FLAC__MetadataType type); ///< See FLAC__stream_decoder_set_metadata_ignore() + virtual bool set_metadata_ignore_application(const FLAC__byte id[4]); ///< See FLAC__stream_decoder_set_metadata_ignore_application() + virtual bool set_metadata_ignore_all(); ///< See FLAC__stream_decoder_set_metadata_ignore_all() + + /* get_state() is not virtual since we want subclasses to be able to return their own state */ + State get_state() const; ///< See FLAC__stream_decoder_get_state() + virtual bool get_md5_checking() const; ///< See FLAC__stream_decoder_get_md5_checking() + virtual FLAC__uint64 get_total_samples() const; ///< See FLAC__stream_decoder_get_total_samples() + virtual unsigned get_channels() const; ///< See FLAC__stream_decoder_get_channels() + virtual ::FLAC__ChannelAssignment get_channel_assignment() const; ///< See FLAC__stream_decoder_get_channel_assignment() + virtual unsigned get_bits_per_sample() const; ///< See FLAC__stream_decoder_get_bits_per_sample() + virtual unsigned get_sample_rate() const; ///< See FLAC__stream_decoder_get_sample_rate() + virtual unsigned get_blocksize() const; ///< See FLAC__stream_decoder_get_blocksize() + virtual bool get_decode_position(FLAC__uint64 *position) const; ///< See FLAC__stream_decoder_get_decode_position() + + virtual ::FLAC__StreamDecoderInitStatus init(); ///< Seek FLAC__stream_decoder_init_stream() + virtual ::FLAC__StreamDecoderInitStatus init_ogg(); ///< Seek FLAC__stream_decoder_init_ogg_stream() + + virtual bool finish(); ///< See FLAC__stream_decoder_finish() + + virtual bool flush(); ///< See FLAC__stream_decoder_flush() + virtual bool reset(); ///< See FLAC__stream_decoder_reset() + + virtual bool process_single(); ///< See FLAC__stream_decoder_process_single() + virtual bool process_until_end_of_metadata(); ///< See FLAC__stream_decoder_process_until_end_of_metadata() + virtual bool process_until_end_of_stream(); ///< See FLAC__stream_decoder_process_until_end_of_stream() + virtual bool skip_single_frame(); ///< See FLAC__stream_decoder_skip_single_frame() + + virtual bool seek_absolute(FLAC__uint64 sample); ///< See FLAC__stream_decoder_seek_absolute() + protected: + /// see FLAC__StreamDecoderReadCallback + virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes) = 0; + + /// see FLAC__StreamDecoderSeekCallback + virtual ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); + + /// see FLAC__StreamDecoderTellCallback + virtual ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); + + /// see FLAC__StreamDecoderLengthCallback + virtual ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length); + + /// see FLAC__StreamDecoderEofCallback + virtual bool eof_callback(); + + /// see FLAC__StreamDecoderWriteCallback + virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0; + + /// see FLAC__StreamDecoderMetadataCallback + virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata); + + /// see FLAC__StreamDecoderErrorCallback + virtual void error_callback(::FLAC__StreamDecoderErrorStatus status) = 0; + +#if (defined __BORLANDC__) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96))) || (defined __SUNPRO_CC) + // lame hack: some compilers can't see a protected decoder_ from nested State::resolved_as_cstring() + friend State; +#endif + ::FLAC__StreamDecoder *decoder_; + + static ::FLAC__StreamDecoderReadStatus read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + static ::FLAC__StreamDecoderSeekStatus seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); + static ::FLAC__StreamDecoderTellStatus tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + static ::FLAC__StreamDecoderLengthStatus length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); + static FLAC__bool eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data); + static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); + static void metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data); + static void error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data); + private: + // Private and undefined so you can't use them: + Stream(const Stream &); + void operator=(const Stream &); + }; + + /** \ingroup flacpp_decoder + * \brief + * This class wraps the ::FLAC__StreamDecoder. If you are + * not decoding from a file, you may need to use + * FLAC::Decoder::Stream. + * + * The usage of this class is similar to FLAC__StreamDecoder, + * except instead of providing callbacks to + * FLAC__stream_decoder_init*_FILE() or + * FLAC__stream_decoder_init*_file(), you will inherit from this + * class and override the virtual callback functions with your + * own implementations, then call init() or init_off(). The rest + * of the calls work the same as in the C layer. + * + * Only the write, and error callbacks from FLAC::Decoder::Stream + * are mandatory. The others are optional; this class provides + * full working implementations for all other callbacks and + * supports seeking. + */ + class FLACPP_API File: public Stream { + public: + File(); + virtual ~File(); + + using Stream::init; + virtual ::FLAC__StreamDecoderInitStatus init(FILE *file); ///< See FLAC__stream_decoder_init_FILE() + virtual ::FLAC__StreamDecoderInitStatus init(const char *filename); ///< See FLAC__stream_decoder_init_file() + virtual ::FLAC__StreamDecoderInitStatus init(const std::string &filename); ///< See FLAC__stream_decoder_init_file() + using Stream::init_ogg; + virtual ::FLAC__StreamDecoderInitStatus init_ogg(FILE *file); ///< See FLAC__stream_decoder_init_ogg_FILE() + virtual ::FLAC__StreamDecoderInitStatus init_ogg(const char *filename); ///< See FLAC__stream_decoder_init_ogg_file() + virtual ::FLAC__StreamDecoderInitStatus init_ogg(const std::string &filename); ///< See FLAC__stream_decoder_init_ogg_file() + protected: + // this is a dummy implementation to satisfy the pure virtual in Stream that is actually supplied internally by the C layer + virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); + private: + // Private and undefined so you can't use them: + File(const File &); + void operator=(const File &); + }; + + } +} + +#endif diff --git a/deps/flac-1.3.2/include/FLAC++/encoder.h b/deps/flac-1.3.2/include/FLAC++/encoder.h new file mode 100644 index 0000000..b01a545 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/encoder.h @@ -0,0 +1,263 @@ +/* libFLAC++ - Free Lossless Audio Codec library + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLACPP__ENCODER_H +#define FLACPP__ENCODER_H + +#include "export.h" + +#include "FLAC/stream_encoder.h" +#include "decoder.h" +#include "metadata.h" + + +/** \file include/FLAC++/encoder.h + * + * \brief + * This module contains the classes which implement the various + * encoders. + * + * See the detailed documentation in the + * \link flacpp_encoder encoder \endlink module. + */ + +/** \defgroup flacpp_encoder FLAC++/encoder.h: encoder classes + * \ingroup flacpp + * + * \brief + * This module describes the encoder layers provided by libFLAC++. + * + * The libFLAC++ encoder classes are object wrappers around their + * counterparts in libFLAC. All encoding layers available in + * libFLAC are also provided here. The interface is very similar; + * make sure to read the \link flac_encoder libFLAC encoder module \endlink. + * + * There are only two significant differences here. First, instead of + * passing in C function pointers for callbacks, you inherit from the + * encoder class and provide implementations for the callbacks in your + * derived class; because of this there is no need for a 'client_data' + * property. + * + * Second, there are two stream encoder classes. FLAC::Encoder::Stream + * is used for the same cases that FLAC__stream_encoder_init_stream() / + * FLAC__stream_encoder_init_ogg_stream() are used, and FLAC::Encoder::File + * is used for the same cases that + * FLAC__stream_encoder_init_FILE() and FLAC__stream_encoder_init_file() / + * FLAC__stream_encoder_init_ogg_FILE() and FLAC__stream_encoder_init_ogg_file() + * are used. + */ + +namespace FLAC { + namespace Encoder { + + /** \ingroup flacpp_encoder + * \brief + * This class wraps the ::FLAC__StreamEncoder. If you are + * encoding to a file, FLAC::Encoder::File may be more + * convenient. + * + * The usage of this class is similar to FLAC__StreamEncoder, + * except instead of providing callbacks to + * FLAC__stream_encoder_init*_stream(), you will inherit from this + * class and override the virtual callback functions with your + * own implementations, then call init() or init_ogg(). The rest of + * the calls work the same as in the C layer. + * + * Only the write callback is mandatory. The others are + * optional; this class provides default implementations that do + * nothing. In order for some STREAMINFO and SEEKTABLE data to + * be written properly, you must overide seek_callback() and + * tell_callback(); see FLAC__stream_encoder_init_stream() as to + * why. + */ + class FLACPP_API Stream { + public: + /** This class is a wrapper around FLAC__StreamEncoderState. + */ + class FLACPP_API State { + public: + inline State(::FLAC__StreamEncoderState state): state_(state) { } + inline operator ::FLAC__StreamEncoderState() const { return state_; } + inline const char *as_cstring() const { return ::FLAC__StreamEncoderStateString[state_]; } + inline const char *resolved_as_cstring(const Stream &encoder) const { return ::FLAC__stream_encoder_get_resolved_state_string(encoder.encoder_); } + protected: + ::FLAC__StreamEncoderState state_; + }; + + Stream(); + virtual ~Stream(); + + //@{ + /** Call after construction to check the that the object was created + * successfully. If not, use get_state() to find out why not. + * + */ + virtual bool is_valid() const; + inline operator bool() const { return is_valid(); } ///< See is_valid() + //@} + + virtual bool set_ogg_serial_number(long value); ///< See FLAC__stream_encoder_set_ogg_serial_number() + virtual bool set_verify(bool value); ///< See FLAC__stream_encoder_set_verify() + virtual bool set_streamable_subset(bool value); ///< See FLAC__stream_encoder_set_streamable_subset() + virtual bool set_channels(unsigned value); ///< See FLAC__stream_encoder_set_channels() + virtual bool set_bits_per_sample(unsigned value); ///< See FLAC__stream_encoder_set_bits_per_sample() + virtual bool set_sample_rate(unsigned value); ///< See FLAC__stream_encoder_set_sample_rate() + virtual bool set_compression_level(unsigned value); ///< See FLAC__stream_encoder_set_compression_level() + virtual bool set_blocksize(unsigned value); ///< See FLAC__stream_encoder_set_blocksize() + virtual bool set_do_mid_side_stereo(bool value); ///< See FLAC__stream_encoder_set_do_mid_side_stereo() + virtual bool set_loose_mid_side_stereo(bool value); ///< See FLAC__stream_encoder_set_loose_mid_side_stereo() + virtual bool set_apodization(const char *specification); ///< See FLAC__stream_encoder_set_apodization() + virtual bool set_max_lpc_order(unsigned value); ///< See FLAC__stream_encoder_set_max_lpc_order() + virtual bool set_qlp_coeff_precision(unsigned value); ///< See FLAC__stream_encoder_set_qlp_coeff_precision() + virtual bool set_do_qlp_coeff_prec_search(bool value); ///< See FLAC__stream_encoder_set_do_qlp_coeff_prec_search() + virtual bool set_do_escape_coding(bool value); ///< See FLAC__stream_encoder_set_do_escape_coding() + virtual bool set_do_exhaustive_model_search(bool value); ///< See FLAC__stream_encoder_set_do_exhaustive_model_search() + virtual bool set_min_residual_partition_order(unsigned value); ///< See FLAC__stream_encoder_set_min_residual_partition_order() + virtual bool set_max_residual_partition_order(unsigned value); ///< See FLAC__stream_encoder_set_max_residual_partition_order() + virtual bool set_rice_parameter_search_dist(unsigned value); ///< See FLAC__stream_encoder_set_rice_parameter_search_dist() + virtual bool set_total_samples_estimate(FLAC__uint64 value); ///< See FLAC__stream_encoder_set_total_samples_estimate() + virtual bool set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks); ///< See FLAC__stream_encoder_set_metadata() + virtual bool set_metadata(FLAC::Metadata::Prototype **metadata, unsigned num_blocks); ///< See FLAC__stream_encoder_set_metadata() + + /* get_state() is not virtual since we want subclasses to be able to return their own state */ + State get_state() const; ///< See FLAC__stream_encoder_get_state() + virtual Decoder::Stream::State get_verify_decoder_state() const; ///< See FLAC__stream_encoder_get_verify_decoder_state() + virtual void get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); ///< See FLAC__stream_encoder_get_verify_decoder_error_stats() + virtual bool get_verify() const; ///< See FLAC__stream_encoder_get_verify() + virtual bool get_streamable_subset() const; ///< See FLAC__stream_encoder_get_streamable_subset() + virtual bool get_do_mid_side_stereo() const; ///< See FLAC__stream_encoder_get_do_mid_side_stereo() + virtual bool get_loose_mid_side_stereo() const; ///< See FLAC__stream_encoder_get_loose_mid_side_stereo() + virtual unsigned get_channels() const; ///< See FLAC__stream_encoder_get_channels() + virtual unsigned get_bits_per_sample() const; ///< See FLAC__stream_encoder_get_bits_per_sample() + virtual unsigned get_sample_rate() const; ///< See FLAC__stream_encoder_get_sample_rate() + virtual unsigned get_blocksize() const; ///< See FLAC__stream_encoder_get_blocksize() + virtual unsigned get_max_lpc_order() const; ///< See FLAC__stream_encoder_get_max_lpc_order() + virtual unsigned get_qlp_coeff_precision() const; ///< See FLAC__stream_encoder_get_qlp_coeff_precision() + virtual bool get_do_qlp_coeff_prec_search() const; ///< See FLAC__stream_encoder_get_do_qlp_coeff_prec_search() + virtual bool get_do_escape_coding() const; ///< See FLAC__stream_encoder_get_do_escape_coding() + virtual bool get_do_exhaustive_model_search() const; ///< See FLAC__stream_encoder_get_do_exhaustive_model_search() + virtual unsigned get_min_residual_partition_order() const; ///< See FLAC__stream_encoder_get_min_residual_partition_order() + virtual unsigned get_max_residual_partition_order() const; ///< See FLAC__stream_encoder_get_max_residual_partition_order() + virtual unsigned get_rice_parameter_search_dist() const; ///< See FLAC__stream_encoder_get_rice_parameter_search_dist() + virtual FLAC__uint64 get_total_samples_estimate() const; ///< See FLAC__stream_encoder_get_total_samples_estimate() + + virtual ::FLAC__StreamEncoderInitStatus init(); ///< See FLAC__stream_encoder_init_stream() + virtual ::FLAC__StreamEncoderInitStatus init_ogg(); ///< See FLAC__stream_encoder_init_ogg_stream() + + virtual bool finish(); ///< See FLAC__stream_encoder_finish() + + virtual bool process(const FLAC__int32 * const buffer[], unsigned samples); ///< See FLAC__stream_encoder_process() + virtual bool process_interleaved(const FLAC__int32 buffer[], unsigned samples); ///< See FLAC__stream_encoder_process_interleaved() + protected: + /// See FLAC__StreamEncoderReadCallback + virtual ::FLAC__StreamEncoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); + + /// See FLAC__StreamEncoderWriteCallback + virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame) = 0; + + /// See FLAC__StreamEncoderSeekCallback + virtual ::FLAC__StreamEncoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); + + /// See FLAC__StreamEncoderTellCallback + virtual ::FLAC__StreamEncoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); + + /// See FLAC__StreamEncoderMetadataCallback + virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata); + +#if (defined __BORLANDC__) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96))) || (defined __SUNPRO_CC) + // lame hack: some compilers can't see a protected encoder_ from nested State::resolved_as_cstring() + friend State; +#endif + ::FLAC__StreamEncoder *encoder_; + + static ::FLAC__StreamEncoderReadStatus read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + static ::FLAC__StreamEncoderWriteStatus write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); + static ::FLAC__StreamEncoderSeekStatus seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); + static ::FLAC__StreamEncoderTellStatus tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + static void metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data); + private: + // Private and undefined so you can't use them: + Stream(const Stream &); + void operator=(const Stream &); + }; + + /** \ingroup flacpp_encoder + * \brief + * This class wraps the ::FLAC__StreamEncoder. If you are + * not encoding to a file, you may need to use + * FLAC::Encoder::Stream. + * + * The usage of this class is similar to FLAC__StreamEncoder, + * except instead of providing callbacks to + * FLAC__stream_encoder_init*_FILE() or + * FLAC__stream_encoder_init*_file(), you will inherit from this + * class and override the virtual callback functions with your + * own implementations, then call init() or init_ogg(). The rest + * of the calls work the same as in the C layer. + * + * There are no mandatory callbacks; all the callbacks from + * FLAC::Encoder::Stream are implemented here fully and support + * full post-encode STREAMINFO and SEEKTABLE updating. There is + * only an optional progress callback which you may override to + * get periodic reports on the progress of the encode. + */ + class FLACPP_API File: public Stream { + public: + File(); + virtual ~File(); + + using Stream::init; + virtual ::FLAC__StreamEncoderInitStatus init(FILE *file); ///< See FLAC__stream_encoder_init_FILE() + virtual ::FLAC__StreamEncoderInitStatus init(const char *filename); ///< See FLAC__stream_encoder_init_file() + virtual ::FLAC__StreamEncoderInitStatus init(const std::string &filename); ///< See FLAC__stream_encoder_init_file() + using Stream::init_ogg; + virtual ::FLAC__StreamEncoderInitStatus init_ogg(FILE *file); ///< See FLAC__stream_encoder_init_ogg_FILE() + virtual ::FLAC__StreamEncoderInitStatus init_ogg(const char *filename); ///< See FLAC__stream_encoder_init_ogg_file() + virtual ::FLAC__StreamEncoderInitStatus init_ogg(const std::string &filename); ///< See FLAC__stream_encoder_init_ogg_file() + protected: + /// See FLAC__StreamEncoderProgressCallback + virtual void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate); + + /// This is a dummy implementation to satisfy the pure virtual in Stream that is actually supplied internally by the C layer + virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame); + private: + static void progress_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); + + // Private and undefined so you can't use them: + File(const Stream &); + void operator=(const Stream &); + }; + + } +} + +#endif diff --git a/deps/flac-1.3.2/include/FLAC++/export.h b/deps/flac-1.3.2/include/FLAC++/export.h new file mode 100644 index 0000000..1645362 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/export.h @@ -0,0 +1,86 @@ +/* libFLAC++ - Free Lossless Audio Codec library + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLACPP__EXPORT_H +#define FLACPP__EXPORT_H + +/** \file include/FLAC++/export.h + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * See the \link flacpp_export export \endlink module. + */ + +/** \defgroup flacpp_export FLAC++/export.h: export symbols + * \ingroup flacpp + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * If you are compiling with MSVC and will link to the static library + * (libFLAC++.lib) you should define FLAC__NO_DLL in your project to + * make sure the symbols are exported properly. + * + * \{ + */ + +#if defined(FLAC__NO_DLL) +#define FLACPP_API + +#elif defined(_MSC_VER) +#ifdef FLACPP_API_EXPORTS +#define FLACPP_API __declspec(dllexport) +#else +#define FLACPP_API __declspec(dllimport) +#endif + +#elif defined(FLAC__USE_VISIBILITY_ATTR) +#define FLACPP_API __attribute__ ((visibility ("default"))) + +#else +#define FLACPP_API + +#endif + +/* These #defines will mirror the libtool-based library version number, see + * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning + */ +#define FLACPP_API_VERSION_CURRENT 9 +#define FLACPP_API_VERSION_REVISION 0 +#define FLACPP_API_VERSION_AGE 3 + +/* \} */ + +#endif diff --git a/deps/flac-1.3.2/include/FLAC++/metadata.h b/deps/flac-1.3.2/include/FLAC++/metadata.h new file mode 100644 index 0000000..60051d6 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC++/metadata.h @@ -0,0 +1,1225 @@ +/* libFLAC++ - Free Lossless Audio Codec library + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLACPP__METADATA_H +#define FLACPP__METADATA_H + +#include "export.h" + +#include "FLAC/metadata.h" + +// =============================================================== +// +// Full documentation for the metadata interface can be found +// in the C layer in include/FLAC/metadata.h +// +// =============================================================== + +/** \file include/FLAC++/metadata.h + * + * \brief + * This module provides classes for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in FLAC files. + * + * See the detailed documentation for each interface in the + * \link flacpp_metadata metadata \endlink module. + */ + +/** \defgroup flacpp_metadata FLAC++/metadata.h: metadata interfaces + * \ingroup flacpp + * + * \brief + * This module provides classes for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in FLAC files. + * + * The behavior closely mimics the C layer interface; be sure to read + * the detailed description of the + * \link flac_metadata C metadata module \endlink. Note that like the + * C layer, currently only the Chain interface (level 2) supports Ogg + * FLAC files, and it is read-only i.e. no writing back changed + * metadata to file. + */ + + +namespace FLAC { + namespace Metadata { + + // ============================================================ + // + // Metadata objects + // + // ============================================================ + + /** \defgroup flacpp_metadata_object FLAC++/metadata.h: metadata object classes + * \ingroup flacpp_metadata + * + * This module contains classes representing FLAC metadata + * blocks in memory. + * + * The behavior closely mimics the C layer interface; be + * sure to read the detailed description of the + * \link flac_metadata_object C metadata object module \endlink. + * + * Any time a metadata object is constructed or assigned, you + * should check is_valid() to make sure the underlying + * ::FLAC__StreamMetadata object was able to be created. + * + * \warning + * When the get_*() methods of any metadata object method + * return you a const pointer, DO NOT disobey and write into it. + * Always use the set_*() methods. + * + * \{ + */ + + /** Base class for all metadata block types. + * See the \link flacpp_metadata_object overview \endlink for more. + */ + class FLACPP_API Prototype { + protected: + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + Prototype(const Prototype &); + Prototype(const ::FLAC__StreamMetadata &); + Prototype(const ::FLAC__StreamMetadata *); + //@} + + /** Constructs an object with copy control. When \a copy + * is \c true, behaves identically to + * FLAC::Metadata::Prototype::Prototype(const ::FLAC__StreamMetadata *object). + * When \a copy is \c false, the instance takes ownership of + * the pointer and the ::FLAC__StreamMetadata object will + * be freed by the destructor. + * + * \assert + * \code object != NULL \endcode + */ + Prototype(::FLAC__StreamMetadata *object, bool copy); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + Prototype &operator=(const Prototype &); + Prototype &operator=(const ::FLAC__StreamMetadata &); + Prototype &operator=(const ::FLAC__StreamMetadata *); + //@} + + /** Assigns an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + Prototype &assign_object(::FLAC__StreamMetadata *object, bool copy); + + /** Deletes the underlying ::FLAC__StreamMetadata object. + */ + virtual void clear(); + + ::FLAC__StreamMetadata *object_; + public: + /** Deletes the underlying ::FLAC__StreamMetadata object. + */ + virtual ~Prototype(); + + //@{ + /** Check for equality, performing a deep compare by following pointers. + */ + inline bool operator==(const Prototype &) const; + inline bool operator==(const ::FLAC__StreamMetadata &) const; + inline bool operator==(const ::FLAC__StreamMetadata *) const; + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const Prototype &) const; + inline bool operator!=(const ::FLAC__StreamMetadata &) const; + inline bool operator!=(const ::FLAC__StreamMetadata *) const; + //@} + + friend class SimpleIterator; + friend class Iterator; + + /** Returns \c true if the object was correctly constructed + * (i.e. the underlying ::FLAC__StreamMetadata object was + * properly allocated), else \c false. + */ + inline bool is_valid() const; + + /** Returns \c true if this block is the last block in a + * stream, else \c false. + * + * \assert + * \code is_valid() \endcode + */ + bool get_is_last() const; + + /** Returns the type of the block. + * + * \assert + * \code is_valid() \endcode + */ + ::FLAC__MetadataType get_type() const; + + /** Returns the stream length of the metadata block. + * + * \note + * The length does not include the metadata block header, + * per spec. + * + * \assert + * \code is_valid() \endcode + */ + unsigned get_length() const; + + /** Sets the "is_last" flag for the block. When using the iterators + * it is not necessary to set this flag; they will do it for you. + * + * \assert + * \code is_valid() \endcode + */ + void set_is_last(bool); + + /** Returns a pointer to the underlying ::FLAC__StreamMetadata + * object. This can be useful for plugging any holes between + * the C++ and C interfaces. + * + * \assert + * \code is_valid() \endcode + */ + inline operator const ::FLAC__StreamMetadata *() const; + private: + /** Private and undefined so you can't use it. */ + Prototype(); + + // These are used only by Iterator + bool is_reference_; + inline void set_reference(bool x) { is_reference_ = x; } + }; + +#ifdef _MSC_VER +// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning) +#pragma warning ( disable : 4800 ) +#endif + + inline bool Prototype::operator==(const Prototype &object) const + { return (bool)::FLAC__metadata_object_is_equal(object_, object.object_); } + + inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const + { return (bool)::FLAC__metadata_object_is_equal(object_, &object); } + + inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const + { return (bool)::FLAC__metadata_object_is_equal(object_, object); } + +#ifdef _MSC_VER +#pragma warning ( default : 4800 ) +#endif + + inline bool Prototype::operator!=(const Prototype &object) const + { return !operator==(object); } + + inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const + { return !operator==(object); } + + inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const + { return !operator==(object); } + + inline bool Prototype::is_valid() const + { return 0 != object_; } + + inline Prototype::operator const ::FLAC__StreamMetadata *() const + { return object_; } + + /** Create a deep copy of an object and return it. */ + FLACPP_API Prototype *clone(const Prototype *); + + + /** STREAMINFO metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_streaminfo">format specification</A>. + */ + class FLACPP_API StreamInfo : public Prototype { + public: + StreamInfo(); + + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline StreamInfo(const StreamInfo &object): Prototype(object) { } + inline StreamInfo(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline StreamInfo(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline StreamInfo(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~StreamInfo(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline StreamInfo &operator=(const StreamInfo &object) { Prototype::operator=(object); return *this; } + inline StreamInfo &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline StreamInfo &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline StreamInfo &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + //@{ + /** See <A HREF="../format.html#metadata_block_streaminfo">format specification</A>. */ + unsigned get_min_blocksize() const; + unsigned get_max_blocksize() const; + unsigned get_min_framesize() const; + unsigned get_max_framesize() const; + unsigned get_sample_rate() const; + unsigned get_channels() const; + unsigned get_bits_per_sample() const; + FLAC__uint64 get_total_samples() const; + const FLAC__byte *get_md5sum() const; + + void set_min_blocksize(unsigned value); + void set_max_blocksize(unsigned value); + void set_min_framesize(unsigned value); + void set_max_framesize(unsigned value); + void set_sample_rate(unsigned value); + void set_channels(unsigned value); + void set_bits_per_sample(unsigned value); + void set_total_samples(FLAC__uint64 value); + void set_md5sum(const FLAC__byte value[16]); + //@} + }; + + /** PADDING metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_padding">format specification</A>. + */ + class FLACPP_API Padding : public Prototype { + public: + Padding(); + + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline Padding(const Padding &object): Prototype(object) { } + inline Padding(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline Padding(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline Padding(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + /** Constructs an object with the given length. + */ + Padding(unsigned length); + + ~Padding(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline Padding &operator=(const Padding &object) { Prototype::operator=(object); return *this; } + inline Padding &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline Padding &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline Padding &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const Padding &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + /** Sets the length in bytes of the padding block. + */ + void set_length(unsigned length); + }; + + /** APPLICATION metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_application">format specification</A>. + */ + class FLACPP_API Application : public Prototype { + public: + Application(); + // + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline Application(const Application &object): Prototype(object) { } + inline Application(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline Application(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline Application(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~Application(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline Application &operator=(const Application &object) { Prototype::operator=(object); return *this; } + inline Application &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline Application &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline Application &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const Application &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + const FLAC__byte *get_id() const; + const FLAC__byte *get_data() const; + + void set_id(const FLAC__byte value[4]); + //! This form always copies \a data + bool set_data(const FLAC__byte *data, unsigned length); + bool set_data(FLAC__byte *data, unsigned length, bool copy); + }; + + /** SEEKTABLE metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_seektable">format specification</A>. + */ + class FLACPP_API SeekTable : public Prototype { + public: + SeekTable(); + + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline SeekTable(const SeekTable &object): Prototype(object) { } + inline SeekTable(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline SeekTable(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline SeekTable(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~SeekTable(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline SeekTable &operator=(const SeekTable &object) { Prototype::operator=(object); return *this; } + inline SeekTable &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline SeekTable &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline SeekTable &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + unsigned get_num_points() const; + ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const; + + //! See FLAC__metadata_object_seektable_resize_points() + bool resize_points(unsigned new_num_points); + + //! See FLAC__metadata_object_seektable_set_point() + void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point); + + //! See FLAC__metadata_object_seektable_insert_point() + bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point); + + //! See FLAC__metadata_object_seektable_delete_point() + bool delete_point(unsigned index); + + //! See FLAC__metadata_object_seektable_is_legal() + bool is_legal() const; + + //! See FLAC__metadata_object_seektable_template_append_placeholders() + bool template_append_placeholders(unsigned num); + + //! See FLAC__metadata_object_seektable_template_append_point() + bool template_append_point(FLAC__uint64 sample_number); + + //! See FLAC__metadata_object_seektable_template_append_points() + bool template_append_points(FLAC__uint64 sample_numbers[], unsigned num); + + //! See FLAC__metadata_object_seektable_template_append_spaced_points() + bool template_append_spaced_points(unsigned num, FLAC__uint64 total_samples); + + //! See FLAC__metadata_object_seektable_template_append_spaced_points_by_samples() + bool template_append_spaced_points_by_samples(unsigned samples, FLAC__uint64 total_samples); + + //! See FLAC__metadata_object_seektable_template_sort() + bool template_sort(bool compact); + }; + + /** VORBIS_COMMENT metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>. + */ + class FLACPP_API VorbisComment : public Prototype { + public: + /** Convenience class for encapsulating Vorbis comment + * entries. An entry is a vendor string or a comment + * field. In the case of a vendor string, the field + * name is undefined; only the field value is relevant. + * + * A \a field as used in the methods refers to an + * entire 'NAME=VALUE' string; for convenience the + * string is NUL-terminated. A length field is + * required in the unlikely event that the value + * contains contain embedded NULs. + * + * A \a field_name is what is on the left side of the + * first '=' in the \a field. By definition it is ASCII + * and so is NUL-terminated and does not require a + * length to describe it. \a field_name is undefined + * for a vendor string entry. + * + * A \a field_value is what is on the right side of the + * first '=' in the \a field. By definition, this may + * contain embedded NULs and so a \a field_value_length + * is required to describe it. However in practice, + * embedded NULs are not known to be used, so it is + * generally safe to treat field values as NUL- + * terminated UTF-8 strings. + * + * Always check is_valid() after the constructor or operator= + * to make sure memory was properly allocated and that the + * Entry conforms to the Vorbis comment specification. + */ + class FLACPP_API Entry { + public: + Entry(); + + Entry(const char *field, unsigned field_length); + Entry(const char *field); // assumes \a field is NUL-terminated + + Entry(const char *field_name, const char *field_value, unsigned field_value_length); + Entry(const char *field_name, const char *field_value); // assumes \a field_value is NUL-terminated + + Entry(const Entry &entry); + + Entry &operator=(const Entry &entry); + + virtual ~Entry(); + + virtual bool is_valid() const; ///< Returns \c true iff object was properly constructed. + + unsigned get_field_length() const; + unsigned get_field_name_length() const; + unsigned get_field_value_length() const; + + ::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const; + const char *get_field() const; + const char *get_field_name() const; + const char *get_field_value() const; + + bool set_field(const char *field, unsigned field_length); + bool set_field(const char *field); // assumes \a field is NUL-terminated + bool set_field_name(const char *field_name); + bool set_field_value(const char *field_value, unsigned field_value_length); + bool set_field_value(const char *field_value); // assumes \a field_value is NUL-terminated + protected: + bool is_valid_; + ::FLAC__StreamMetadata_VorbisComment_Entry entry_; + char *field_name_; + unsigned field_name_length_; + char *field_value_; + unsigned field_value_length_; + private: + void zero(); + void clear(); + void clear_entry(); + void clear_field_name(); + void clear_field_value(); + void construct(const char *field, unsigned field_length); + void construct(const char *field); // assumes \a field is NUL-terminated + void construct(const char *field_name, const char *field_value, unsigned field_value_length); + void construct(const char *field_name, const char *field_value); // assumes \a field_value is NUL-terminated + void compose_field(); + void parse_field(); + }; + + VorbisComment(); + + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline VorbisComment(const VorbisComment &object): Prototype(object) { } + inline VorbisComment(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline VorbisComment(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline VorbisComment(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~VorbisComment(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline VorbisComment &operator=(const VorbisComment &object) { Prototype::operator=(object); return *this; } + inline VorbisComment &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline VorbisComment &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline VorbisComment &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + unsigned get_num_comments() const; + const FLAC__byte *get_vendor_string() const; // NUL-terminated UTF-8 string + Entry get_comment(unsigned index) const; + + //! See FLAC__metadata_object_vorbiscomment_set_vendor_string() + bool set_vendor_string(const FLAC__byte *string); // NUL-terminated UTF-8 string + + //! See FLAC__metadata_object_vorbiscomment_resize_comments() + bool resize_comments(unsigned new_num_comments); + + //! See FLAC__metadata_object_vorbiscomment_set_comment() + bool set_comment(unsigned index, const Entry &entry); + + //! See FLAC__metadata_object_vorbiscomment_insert_comment() + bool insert_comment(unsigned index, const Entry &entry); + + //! See FLAC__metadata_object_vorbiscomment_append_comment() + bool append_comment(const Entry &entry); + + //! See FLAC__metadata_object_vorbiscomment_replace_comment() + bool replace_comment(const Entry &entry, bool all); + + //! See FLAC__metadata_object_vorbiscomment_delete_comment() + bool delete_comment(unsigned index); + + //! See FLAC__metadata_object_vorbiscomment_find_entry_from() + int find_entry_from(unsigned offset, const char *field_name); + + //! See FLAC__metadata_object_vorbiscomment_remove_entry_matching() + int remove_entry_matching(const char *field_name); + + //! See FLAC__metadata_object_vorbiscomment_remove_entries_matching() + int remove_entries_matching(const char *field_name); + }; + + /** CUESHEET metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_cuesheet">format specification</A>. + */ + class FLACPP_API CueSheet : public Prototype { + public: + /** Convenience class for encapsulating a cue sheet + * track. + * + * Always check is_valid() after the constructor or operator= + * to make sure memory was properly allocated. + */ + class FLACPP_API Track { + protected: + ::FLAC__StreamMetadata_CueSheet_Track *object_; + public: + Track(); + Track(const ::FLAC__StreamMetadata_CueSheet_Track *track); + Track(const Track &track); + Track &operator=(const Track &track); + + virtual ~Track(); + + virtual bool is_valid() const; ///< Returns \c true iff object was properly constructed. + + + inline FLAC__uint64 get_offset() const { return object_->offset; } + inline FLAC__byte get_number() const { return object_->number; } + inline const char *get_isrc() const { return object_->isrc; } + inline unsigned get_type() const { return object_->type; } + inline bool get_pre_emphasis() const { return object_->pre_emphasis; } + + inline FLAC__byte get_num_indices() const { return object_->num_indices; } + ::FLAC__StreamMetadata_CueSheet_Index get_index(unsigned i) const; + + inline const ::FLAC__StreamMetadata_CueSheet_Track *get_track() const { return object_; } + + inline void set_offset(FLAC__uint64 value) { object_->offset = value; } + inline void set_number(FLAC__byte value) { object_->number = value; } + void set_isrc(const char value[12]); + void set_type(unsigned value); + inline void set_pre_emphasis(bool value) { object_->pre_emphasis = value? 1 : 0; } + + void set_index(unsigned i, const ::FLAC__StreamMetadata_CueSheet_Index &index); + //@@@ It's awkward but to insert/delete index points + //@@@ you must use the routines in the CueSheet class. + }; + + CueSheet(); + + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline CueSheet(const CueSheet &object): Prototype(object) { } + inline CueSheet(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline CueSheet(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline CueSheet(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~CueSheet(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline CueSheet &operator=(const CueSheet &object) { Prototype::operator=(object); return *this; } + inline CueSheet &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline CueSheet &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline CueSheet &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const CueSheet &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const CueSheet &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + const char *get_media_catalog_number() const; + FLAC__uint64 get_lead_in() const; + bool get_is_cd() const; + + unsigned get_num_tracks() const; + Track get_track(unsigned i) const; + + void set_media_catalog_number(const char value[128]); + void set_lead_in(FLAC__uint64 value); + void set_is_cd(bool value); + + void set_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index); + + //! See FLAC__metadata_object_cuesheet_track_resize_indices() + bool resize_indices(unsigned track_num, unsigned new_num_indices); + + //! See FLAC__metadata_object_cuesheet_track_insert_index() + bool insert_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index); + + //! See FLAC__metadata_object_cuesheet_track_insert_blank_index() + bool insert_blank_index(unsigned track_num, unsigned index_num); + + //! See FLAC__metadata_object_cuesheet_track_delete_index() + bool delete_index(unsigned track_num, unsigned index_num); + + //! See FLAC__metadata_object_cuesheet_resize_tracks() + bool resize_tracks(unsigned new_num_tracks); + + //! See FLAC__metadata_object_cuesheet_set_track() + bool set_track(unsigned i, const Track &track); + + //! See FLAC__metadata_object_cuesheet_insert_track() + bool insert_track(unsigned i, const Track &track); + + //! See FLAC__metadata_object_cuesheet_insert_blank_track() + bool insert_blank_track(unsigned i); + + //! See FLAC__metadata_object_cuesheet_delete_track() + bool delete_track(unsigned i); + + //! See FLAC__metadata_object_cuesheet_is_legal() + bool is_legal(bool check_cd_da_subset = false, const char **violation = 0) const; + + //! See FLAC__metadata_object_cuesheet_calculate_cddb_id() + FLAC__uint32 calculate_cddb_id() const; + }; + + /** PICTURE metadata block. + * See the \link flacpp_metadata_object overview \endlink for more, + * and the <A HREF="../format.html#metadata_block_picture">format specification</A>. + */ + class FLACPP_API Picture : public Prototype { + public: + Picture(); + + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline Picture(const Picture &object): Prototype(object) { } + inline Picture(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline Picture(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline Picture(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~Picture(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline Picture &operator=(const Picture &object) { Prototype::operator=(object); return *this; } + inline Picture &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline Picture &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline Picture &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const Picture &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const Picture &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + ::FLAC__StreamMetadata_Picture_Type get_type() const; + const char *get_mime_type() const; // NUL-terminated printable ASCII string + const FLAC__byte *get_description() const; // NUL-terminated UTF-8 string + FLAC__uint32 get_width() const; + FLAC__uint32 get_height() const; + FLAC__uint32 get_depth() const; + FLAC__uint32 get_colors() const; ///< a return value of \c 0 means true-color, i.e. 2^depth colors + FLAC__uint32 get_data_length() const; + const FLAC__byte *get_data() const; + + void set_type(::FLAC__StreamMetadata_Picture_Type type); + + //! See FLAC__metadata_object_picture_set_mime_type() + bool set_mime_type(const char *string); // NUL-terminated printable ASCII string + + //! See FLAC__metadata_object_picture_set_description() + bool set_description(const FLAC__byte *string); // NUL-terminated UTF-8 string + + void set_width(FLAC__uint32 value) const; + void set_height(FLAC__uint32 value) const; + void set_depth(FLAC__uint32 value) const; + void set_colors(FLAC__uint32 value) const; ///< a value of \c 0 means true-color, i.e. 2^depth colors + + //! See FLAC__metadata_object_picture_set_data() + bool set_data(const FLAC__byte *data, FLAC__uint32 data_length); + + //! See FLAC__metadata_object_picture_is_legal() + bool is_legal(const char **violation); + }; + + /** Opaque metadata block for storing unknown types. + * This should not be used unless you know what you are doing; + * it is currently used only internally to support forward + * compatibility of metadata blocks. + * See the \link flacpp_metadata_object overview \endlink for more, + */ + class FLACPP_API Unknown : public Prototype { + public: + Unknown(); + // + //@{ + /** Constructs a copy of the given object. This form + * always performs a deep copy. + */ + inline Unknown(const Unknown &object): Prototype(object) { } + inline Unknown(const ::FLAC__StreamMetadata &object): Prototype(object) { } + inline Unknown(const ::FLAC__StreamMetadata *object): Prototype(object) { } + //@} + + /** Constructs an object with copy control. See + * Prototype(::FLAC__StreamMetadata *object, bool copy). + */ + inline Unknown(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } + + ~Unknown(); + + //@{ + /** Assign from another object. Always performs a deep copy. */ + inline Unknown &operator=(const Unknown &object) { Prototype::operator=(object); return *this; } + inline Unknown &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } + inline Unknown &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } + //@} + + /** Assigns an object with copy control. See + * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). + */ + inline Unknown &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } + + //@{ + /** Check for equality, performing a deep compare by following pointers. */ + inline bool operator==(const Unknown &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } + //@} + + //@{ + /** Check for inequality, performing a deep compare by following pointers. */ + inline bool operator!=(const Unknown &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } + //@} + + const FLAC__byte *get_data() const; + + //! This form always copies \a data + bool set_data(const FLAC__byte *data, unsigned length); + bool set_data(FLAC__byte *data, unsigned length, bool copy); + }; + + /* \} */ + + + /** \defgroup flacpp_metadata_level0 FLAC++/metadata.h: metadata level 0 interface + * \ingroup flacpp_metadata + * + * \brief + * Level 0 metadata iterators. + * + * See the \link flac_metadata_level0 C layer equivalent \endlink + * for more. + * + * \{ + */ + + FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo); ///< See FLAC__metadata_get_streaminfo(). + + FLACPP_API bool get_tags(const char *filename, VorbisComment *&tags); ///< See FLAC__metadata_get_tags(). + FLACPP_API bool get_tags(const char *filename, VorbisComment &tags); ///< See FLAC__metadata_get_tags(). + + FLACPP_API bool get_cuesheet(const char *filename, CueSheet *&cuesheet); ///< See FLAC__metadata_get_cuesheet(). + FLACPP_API bool get_cuesheet(const char *filename, CueSheet &cuesheet); ///< See FLAC__metadata_get_cuesheet(). + + FLACPP_API bool get_picture(const char *filename, Picture *&picture, ::FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); ///< See FLAC__metadata_get_picture(). + FLACPP_API bool get_picture(const char *filename, Picture &picture, ::FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); ///< See FLAC__metadata_get_picture(). + + /* \} */ + + + /** \defgroup flacpp_metadata_level1 FLAC++/metadata.h: metadata level 1 interface + * \ingroup flacpp_metadata + * + * \brief + * Level 1 metadata iterator. + * + * The flow through the iterator in the C++ layer is similar + * to the C layer: + * - Create a SimpleIterator instance + * - Check SimpleIterator::is_valid() + * - Call SimpleIterator::init() and check the return + * - Traverse and/or edit. Edits are written to file + * immediately. + * - Destroy the SimpleIterator instance + * + * The ownership of pointers in the C++ layer follows that in + * the C layer, i.e. + * - The objects returned by get_block() are yours to + * modify, but changes are not reflected in the FLAC file + * until you call set_block(). The objects are also + * yours to delete; they are not automatically deleted + * when passed to set_block() or insert_block_after(). + * + * See the \link flac_metadata_level1 C layer equivalent \endlink + * for more. + * + * \{ + */ + + /** This class is a wrapper around the FLAC__metadata_simple_iterator + * structures and methods; see the + * \link flacpp_metadata_level1 usage guide \endlink and + * ::FLAC__Metadata_SimpleIterator. + */ + class FLACPP_API SimpleIterator { + public: + /** This class is a wrapper around FLAC__Metadata_SimpleIteratorStatus. + */ + class FLACPP_API Status { + public: + inline Status(::FLAC__Metadata_SimpleIteratorStatus status): status_(status) { } + inline operator ::FLAC__Metadata_SimpleIteratorStatus() const { return status_; } + inline const char *as_cstring() const { return ::FLAC__Metadata_SimpleIteratorStatusString[status_]; } + protected: + ::FLAC__Metadata_SimpleIteratorStatus status_; + }; + + SimpleIterator(); + virtual ~SimpleIterator(); + + bool is_valid() const; ///< Returns \c true iff object was properly constructed. + + bool init(const char *filename, bool read_only, bool preserve_file_stats); ///< See FLAC__metadata_simple_iterator_init(). + + Status status(); ///< See FLAC__metadata_simple_iterator_status(). + bool is_writable() const; ///< See FLAC__metadata_simple_iterator_is_writable(). + + bool next(); ///< See FLAC__metadata_simple_iterator_next(). + bool prev(); ///< See FLAC__metadata_simple_iterator_prev(). + bool is_last() const; ///< See FLAC__metadata_simple_iterator_is_last(). + + off_t get_block_offset() const; ///< See FLAC__metadata_simple_iterator_get_block_offset(). + ::FLAC__MetadataType get_block_type() const; ///< See FLAC__metadata_simple_iterator_get_block_type(). + unsigned get_block_length() const; ///< See FLAC__metadata_simple_iterator_get_block_length(). + bool get_application_id(FLAC__byte *id); ///< See FLAC__metadata_simple_iterator_get_application_id(). + Prototype *get_block(); ///< See FLAC__metadata_simple_iterator_get_block(). + bool set_block(Prototype *block, bool use_padding = true); ///< See FLAC__metadata_simple_iterator_set_block(). + bool insert_block_after(Prototype *block, bool use_padding = true); ///< See FLAC__metadata_simple_iterator_insert_block_after(). + bool delete_block(bool use_padding = true); ///< See FLAC__metadata_simple_iterator_delete_block(). + + protected: + ::FLAC__Metadata_SimpleIterator *iterator_; + void clear(); + + private: // Do not use. + SimpleIterator(const SimpleIterator&); + SimpleIterator&operator=(const SimpleIterator&); + }; + + /* \} */ + + + /** \defgroup flacpp_metadata_level2 FLAC++/metadata.h: metadata level 2 interface + * \ingroup flacpp_metadata + * + * \brief + * Level 2 metadata iterator. + * + * The flow through the iterator in the C++ layer is similar + * to the C layer: + * - Create a Chain instance + * - Check Chain::is_valid() + * - Call Chain::read() and check the return + * - Traverse and/or edit with an Iterator or with + * Chain::merge_padding() or Chain::sort_padding() + * - Write changes back to FLAC file with Chain::write() + * - Destroy the Chain instance + * + * The ownership of pointers in the C++ layer is slightly + * different than in the C layer, i.e. + * - The objects returned by Iterator::get_block() are NOT + * owned by the iterator and should be deleted by the + * caller when finished, BUT, when you modify the block, + * it will directly edit what's in the chain and you do + * not need to call Iterator::set_block(). However the + * changes will not be reflected in the FLAC file until + * the chain is written with Chain::write(). + * - When you pass an object to Iterator::set_block(), + * Iterator::insert_block_before(), or + * Iterator::insert_block_after(), the iterator takes + * ownership of the block and it will be deleted by the + * chain. + * + * See the \link flac_metadata_level2 C layer equivalent \endlink + * for more. + * + * \{ + */ + + /** This class is a wrapper around the FLAC__metadata_chain + * structures and methods; see the + * \link flacpp_metadata_level2 usage guide \endlink and + * ::FLAC__Metadata_Chain. + */ + class FLACPP_API Chain { + public: + /** This class is a wrapper around FLAC__Metadata_ChainStatus. + */ + class FLACPP_API Status { + public: + inline Status(::FLAC__Metadata_ChainStatus status): status_(status) { } + inline operator ::FLAC__Metadata_ChainStatus() const { return status_; } + inline const char *as_cstring() const { return ::FLAC__Metadata_ChainStatusString[status_]; } + protected: + ::FLAC__Metadata_ChainStatus status_; + }; + + Chain(); + virtual ~Chain(); + + friend class Iterator; + + bool is_valid() const; ///< Returns \c true iff object was properly constructed. + + Status status(); ///< See FLAC__metadata_chain_status(). + + bool read(const char *filename, bool is_ogg = false); ///< See FLAC__metadata_chain_read(), FLAC__metadata_chain_read_ogg(). + bool read(FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, bool is_ogg = false); ///< See FLAC__metadata_chain_read_with_callbacks(), FLAC__metadata_chain_read_ogg_with_callbacks(). + + bool check_if_tempfile_needed(bool use_padding); ///< See FLAC__metadata_chain_check_if_tempfile_needed(). + + bool write(bool use_padding = true, bool preserve_file_stats = false); ///< See FLAC__metadata_chain_write(). + bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks); ///< See FLAC__metadata_chain_write_with_callbacks(). + bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks, ::FLAC__IOHandle temp_handle, ::FLAC__IOCallbacks temp_callbacks); ///< See FLAC__metadata_chain_write_with_callbacks_and_tempfile(). + + void merge_padding(); ///< See FLAC__metadata_chain_merge_padding(). + void sort_padding(); ///< See FLAC__metadata_chain_sort_padding(). + + protected: + ::FLAC__Metadata_Chain *chain_; + virtual void clear(); + + private: // Do not use. + Chain(const Chain&); + Chain&operator=(const Chain&); + }; + + /** This class is a wrapper around the FLAC__metadata_iterator + * structures and methods; see the + * \link flacpp_metadata_level2 usage guide \endlink and + * ::FLAC__Metadata_Iterator. + */ + class FLACPP_API Iterator { + public: + Iterator(); + virtual ~Iterator(); + + bool is_valid() const; ///< Returns \c true iff object was properly constructed. + + + void init(Chain &chain); ///< See FLAC__metadata_iterator_init(). + + bool next(); ///< See FLAC__metadata_iterator_next(). + bool prev(); ///< See FLAC__metadata_iterator_prev(). + + ::FLAC__MetadataType get_block_type() const; ///< See FLAC__metadata_iterator_get_block_type(). + Prototype *get_block(); ///< See FLAC__metadata_iterator_get_block(). + bool set_block(Prototype *block); ///< See FLAC__metadata_iterator_set_block(). + bool delete_block(bool replace_with_padding); ///< See FLAC__metadata_iterator_delete_block(). + bool insert_block_before(Prototype *block); ///< See FLAC__metadata_iterator_insert_block_before(). + bool insert_block_after(Prototype *block); ///< See FLAC__metadata_iterator_insert_block_after(). + + protected: + ::FLAC__Metadata_Iterator *iterator_; + virtual void clear(); + + private: // Do not use. + Iterator(const Iterator&); + Iterator&operator=(const Iterator&); + }; + + /* \} */ + + } +} + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/Makefile.am b/deps/flac-1.3.2/include/FLAC/Makefile.am new file mode 100644 index 0000000..82aca28 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/Makefile.am @@ -0,0 +1,43 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2000-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +flaccincludedir = $(includedir)/FLAC + +flaccinclude_HEADERS = \ + all.h \ + assert.h \ + callback.h \ + export.h \ + format.h \ + metadata.h \ + ordinals.h \ + stream_decoder.h \ + stream_encoder.h diff --git a/deps/flac-1.3.2/include/FLAC/Makefile.in b/deps/flac-1.3.2/include/FLAC/Makefile.in new file mode 100644 index 0000000..6da9789 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/Makefile.in @@ -0,0 +1,643 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2000-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/FLAC +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(flaccinclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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)$(flaccincludedir)" +HEADERS = $(flaccinclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +flaccincludedir = $(includedir)/FLAC +flaccinclude_HEADERS = \ + all.h \ + assert.h \ + callback.h \ + export.h \ + format.h \ + metadata.h \ + ordinals.h \ + stream_decoder.h \ + stream_encoder.h + +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 include/FLAC/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/FLAC/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-flaccincludeHEADERS: $(flaccinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(flaccinclude_HEADERS)'; test -n "$(flaccincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(flaccincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(flaccincludedir)" || exit 1; \ + fi; \ + 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)$(flaccincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(flaccincludedir)" || exit $$?; \ + done + +uninstall-flaccincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(flaccinclude_HEADERS)'; test -n "$(flaccincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(flaccincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(flaccincludedir)"; 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 distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-flaccincludeHEADERS + +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 -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-flaccincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + 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-flaccincludeHEADERS \ + 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-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-flaccincludeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/include/FLAC/all.h b/deps/flac-1.3.2/include/FLAC/all.h new file mode 100644 index 0000000..11d47d7 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/all.h @@ -0,0 +1,371 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__ALL_H +#define FLAC__ALL_H + +#include "export.h" + +#include "assert.h" +#include "callback.h" +#include "format.h" +#include "metadata.h" +#include "ordinals.h" +#include "stream_decoder.h" +#include "stream_encoder.h" + +/** \mainpage + * + * \section intro Introduction + * + * This is the documentation for the FLAC C and C++ APIs. It is + * highly interconnected; this introduction should give you a top + * level idea of the structure and how to find the information you + * need. As a prerequisite you should have at least a basic + * knowledge of the FLAC format, documented + * <A HREF="../format.html">here</A>. + * + * \section c_api FLAC C API + * + * The FLAC C API is the interface to libFLAC, a set of structures + * describing the components of FLAC streams, and functions for + * encoding and decoding streams, as well as manipulating FLAC + * metadata in files. The public include files will be installed + * in your include area (for example /usr/include/FLAC/...). + * + * By writing a little code and linking against libFLAC, it is + * relatively easy to add FLAC support to another program. The + * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>. + * Complete source code of libFLAC as well as the command-line + * encoder and plugins is available and is a useful source of + * examples. + * + * Aside from encoders and decoders, libFLAC provides a powerful + * metadata interface for manipulating metadata in FLAC files. It + * allows the user to add, delete, and modify FLAC metadata blocks + * and it can automatically take advantage of PADDING blocks to avoid + * rewriting the entire FLAC file when changing the size of the + * metadata. + * + * libFLAC usually only requires the standard C library and C math + * library. In particular, threading is not used so there is no + * dependency on a thread library. However, libFLAC does not use + * global variables and should be thread-safe. + * + * libFLAC also supports encoding to and decoding from Ogg FLAC. + * However the metadata editing interfaces currently have limited + * read-only support for Ogg FLAC files. + * + * \section cpp_api FLAC C++ API + * + * The FLAC C++ API is a set of classes that encapsulate the + * structures and functions in libFLAC. They provide slightly more + * functionality with respect to metadata but are otherwise + * equivalent. For the most part, they share the same usage as + * their counterparts in libFLAC, and the FLAC C API documentation + * can be used as a supplement. The public include files + * for the C++ API will be installed in your include area (for + * example /usr/include/FLAC++/...). + * + * libFLAC++ is also licensed under + * <A HREF="../license.html">Xiph's BSD license</A>. + * + * \section getting_started Getting Started + * + * A good starting point for learning the API is to browse through + * the <A HREF="modules.html">modules</A>. Modules are logical + * groupings of related functions or classes, which correspond roughly + * to header files or sections of header files. Each module includes a + * detailed description of the general usage of its functions or + * classes. + * + * From there you can go on to look at the documentation of + * individual functions. You can see different views of the individual + * functions through the links in top bar across this page. + * + * If you prefer a more hands-on approach, you can jump right to some + * <A HREF="../documentation_example_code.html">example code</A>. + * + * \section porting_guide Porting Guide + * + * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink + * has been introduced which gives detailed instructions on how to + * port your code to newer versions of FLAC. + * + * \section embedded_developers Embedded Developers + * + * libFLAC has grown larger over time as more functionality has been + * included, but much of it may be unnecessary for a particular embedded + * implementation. Unused parts may be pruned by some simple editing of + * src/libFLAC/Makefile.am. In general, the decoders, encoders, and + * metadata interface are all independent from each other. + * + * It is easiest to just describe the dependencies: + * + * - All modules depend on the \link flac_format Format \endlink module. + * - The decoders and encoders depend on the bitbuffer. + * - The decoder is independent of the encoder. The encoder uses the + * decoder because of the verify feature, but this can be removed if + * not needed. + * - Parts of the metadata interface require the stream decoder (but not + * the encoder). + * - Ogg support is selectable through the compile time macro + * \c FLAC__HAS_OGG. + * + * For example, if your application only requires the stream decoder, no + * encoder, and no metadata interface, you can remove the stream encoder + * and the metadata interface, which will greatly reduce the size of the + * library. + * + * Also, there are several places in the libFLAC code with comments marked + * with "OPT:" where a #define can be changed to enable code that might be + * faster on a specific platform. Experimenting with these can yield faster + * binaries. + */ + +/** \defgroup porting Porting Guide for New Versions + * + * This module describes differences in the library interfaces from + * version to version. It assists in the porting of code that uses + * the libraries to newer versions of FLAC. + * + * One simple facility for making porting easier that has been added + * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each + * library's includes (e.g. \c include/FLAC/export.h). The + * \c #defines mirror the libraries' + * <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>, + * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT, + * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. + * These can be used to support multiple versions of an API during the + * transition phase, e.g. + * + * \code + * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 + * legacy code + * #else + * new code + * #endif + * \endcode + * + * The source will work for multiple versions and the legacy code can + * easily be removed when the transition is complete. + * + * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in + * include/FLAC/export.h), which can be used to determine whether or not + * the library has been compiled with support for Ogg FLAC. This is + * simpler than trying to call an Ogg init function and catching the + * error. + */ + +/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3. + * + * The main change between the APIs in 1.1.2 and 1.1.3 is that they have + * been simplified. First, libOggFLAC has been merged into libFLAC and + * libOggFLAC++ has been merged into libFLAC++. Second, both the three + * decoding layers and three encoding layers have been merged into a + * single stream decoder and stream encoder. That is, the functionality + * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged + * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and + * FLAC__FileEncoder into FLAC__StreamEncoder. Only the + * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means + * is there is now a single API that can be used to encode or decode + * streams to/from native FLAC or Ogg FLAC and the single API can work + * on both seekable and non-seekable streams. + * + * Instead of creating an encoder or decoder of a certain layer, now the + * client will always create a FLAC__StreamEncoder or + * FLAC__StreamDecoder. The old layers are now differentiated by the + * initialization function. For example, for the decoder, + * FLAC__stream_decoder_init() has been replaced by + * FLAC__stream_decoder_init_stream(). This init function takes + * callbacks for the I/O, and the seeking callbacks are optional. This + * allows the client to use the same object for seekable and + * non-seekable streams. For decoding a FLAC file directly, the client + * can use FLAC__stream_decoder_init_file() and pass just a filename + * and fewer callbacks; most of the other callbacks are supplied + * internally. For situations where fopen()ing by filename is not + * possible (e.g. Unicode filenames on Windows) the client can instead + * open the file itself and supply the FILE* to + * FLAC__stream_decoder_init_FILE(). The init functions now returns a + * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. + * Since the callbacks and client data are now passed to the init + * function, the FLAC__stream_decoder_set_*_callback() functions and + * FLAC__stream_decoder_set_client_data() are no longer needed. The + * rest of the calls to the decoder are the same as before. + * + * There are counterpart init functions for Ogg FLAC, e.g. + * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls + * and callbacks are the same as for native FLAC. + * + * As an example, in FLAC 1.1.2 a seekable stream decoder would have + * been set up like so: + * + * \code + * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new(); + * if(decoder == NULL) do_something; + * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true); + * [... other settings ...] + * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback); + * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback); + * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback); + * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback); + * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback); + * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback); + * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback); + * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback); + * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data); + * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something; + * \endcode + * + * In FLAC 1.1.3 it is like this: + * + * \code + * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); + * if(decoder == NULL) do_something; + * FLAC__stream_decoder_set_md5_checking(decoder, true); + * [... other settings ...] + * if(FLAC__stream_decoder_init_stream( + * decoder, + * my_read_callback, + * my_seek_callback, // or NULL + * my_tell_callback, // or NULL + * my_length_callback, // or NULL + * my_eof_callback, // or NULL + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * or you could do; + * + * \code + * [...] + * FILE *file = fopen("somefile.flac","rb"); + * if(file == NULL) do_somthing; + * if(FLAC__stream_decoder_init_FILE( + * decoder, + * file, + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * or just: + * + * \code + * [...] + * if(FLAC__stream_decoder_init_file( + * decoder, + * "somefile.flac", + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * Another small change to the decoder is in how it handles unparseable + * streams. Before, when the decoder found an unparseable stream + * (reserved for when the decoder encounters a stream from a future + * encoder that it can't parse), it changed the state to + * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead + * drops sync and calls the error callback with a new error code + * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is + * more robust. If your error callback does not discriminate on the the + * error state, your code does not need to be changed. + * + * The encoder now has a new setting: + * FLAC__stream_encoder_set_apodization(). This is for setting the + * method used to window the data before LPC analysis. You only need to + * add a call to this function if the default is not suitable. There + * are also two new convenience functions that may be useful: + * FLAC__metadata_object_cuesheet_calculate_cddb_id() and + * FLAC__metadata_get_cuesheet(). + * + * The \a bytes parameter to FLAC__StreamDecoderReadCallback, + * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback + * is now \c size_t instead of \c unsigned. + */ + +/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4. + * + * There were no changes to any of the interfaces from 1.1.3 to 1.1.4. + * There was a slight change in the implementation of + * FLAC__stream_encoder_set_metadata(); the function now makes a copy + * of the \a metadata array of pointers so the client no longer needs + * to maintain it after the call. The objects themselves that are + * pointed to by the array are still not copied though and must be + * maintained until the call to FLAC__stream_encoder_finish(). + */ + +/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0. + * + * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0. + * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added. + * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added. + * + * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN + * has changed to reflect the conversion of one of the reserved bits + * into active use. It used to be \c 2 and now is \c 1. However the + * FLAC frame header length has not changed, so to skip the proper + * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN + + * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN + */ + +/** \defgroup flac FLAC C API + * + * The FLAC C API is the interface to libFLAC, a set of structures + * describing the components of FLAC streams, and functions for + * encoding and decoding streams, as well as manipulating FLAC + * metadata in files. + * + * You should start with the format components as all other modules + * are dependent on it. + */ + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/assert.h b/deps/flac-1.3.2/include/FLAC/assert.h new file mode 100644 index 0000000..b546fd0 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/assert.h @@ -0,0 +1,46 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__ASSERT_H +#define FLAC__ASSERT_H + +/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ +#ifdef DEBUG +#include <assert.h> +#define FLAC__ASSERT(x) assert(x) +#define FLAC__ASSERT_DECLARATION(x) x +#else +#define FLAC__ASSERT(x) +#define FLAC__ASSERT_DECLARATION(x) +#endif + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/callback.h b/deps/flac-1.3.2/include/FLAC/callback.h new file mode 100644 index 0000000..f942dd2 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/callback.h @@ -0,0 +1,185 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__CALLBACK_H +#define FLAC__CALLBACK_H + +#include "ordinals.h" +#include <stdlib.h> /* for size_t */ + +/** \file include/FLAC/callback.h + * + * \brief + * This module defines the structures for describing I/O callbacks + * to the other FLAC interfaces. + * + * See the detailed documentation for callbacks in the + * \link flac_callbacks callbacks \endlink module. + */ + +/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures + * \ingroup flac + * + * \brief + * This module defines the structures for describing I/O callbacks + * to the other FLAC interfaces. + * + * The purpose of the I/O callback functions is to create a common way + * for the metadata interfaces to handle I/O. + * + * Originally the metadata interfaces required filenames as the way of + * specifying FLAC files to operate on. This is problematic in some + * environments so there is an additional option to specify a set of + * callbacks for doing I/O on the FLAC file, instead of the filename. + * + * In addition to the callbacks, a FLAC__IOHandle type is defined as an + * opaque structure for a data source. + * + * The callback function prototypes are similar (but not identical) to the + * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use + * stdio streams to implement the callbacks, you can pass fread, fwrite, and + * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or + * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle + * is required. \warning You generally CANNOT directly use fseek or ftell + * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems + * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with + * large files. You will have to find an equivalent function (e.g. ftello), + * or write a wrapper. The same is true for feof() since this is usually + * implemented as a macro, not as a function whose address can be taken. + * + * \{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** This is the opaque handle type used by the callbacks. Typically + * this is a \c FILE* or address of a file descriptor. + */ +typedef void* FLAC__IOHandle; + +/** Signature for the read callback. + * The signature and semantics match POSIX fread() implementations + * and can generally be used interchangeably. + * + * \param ptr The address of the read buffer. + * \param size The size of the records to be read. + * \param nmemb The number of records to be read. + * \param handle The handle to the data source. + * \retval size_t + * The number of records read. + */ +typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + +/** Signature for the write callback. + * The signature and semantics match POSIX fwrite() implementations + * and can generally be used interchangeably. + * + * \param ptr The address of the write buffer. + * \param size The size of the records to be written. + * \param nmemb The number of records to be written. + * \param handle The handle to the data source. + * \retval size_t + * The number of records written. + */ +typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + +/** Signature for the seek callback. + * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT + * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' + * and 32-bits wide. + * + * \param handle The handle to the data source. + * \param offset The new position, relative to \a whence + * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END + * \retval int + * \c 0 on success, \c -1 on error. + */ +typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); + +/** Signature for the tell callback. + * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT + * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' + * and 32-bits wide. + * + * \param handle The handle to the data source. + * \retval FLAC__int64 + * The current position on success, \c -1 on error. + */ +typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); + +/** Signature for the EOF callback. + * The signature and semantics mostly match POSIX feof() but WATCHOUT: + * on many systems, feof() is a macro, so in this case a wrapper function + * must be provided instead. + * + * \param handle The handle to the data source. + * \retval int + * \c 0 if not at end of file, nonzero if at end of file. + */ +typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); + +/** Signature for the close callback. + * The signature and semantics match POSIX fclose() implementations + * and can generally be used interchangeably. + * + * \param handle The handle to the data source. + * \retval int + * \c 0 on success, \c EOF on error. + */ +typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); + +/** A structure for holding a set of callbacks. + * Each FLAC interface that requires a FLAC__IOCallbacks structure will + * describe which of the callbacks are required. The ones that are not + * required may be set to NULL. + * + * If the seek requirement for an interface is optional, you can signify that + * a data sorce is not seekable by setting the \a seek field to \c NULL. + */ +typedef struct { + FLAC__IOCallback_Read read; + FLAC__IOCallback_Write write; + FLAC__IOCallback_Seek seek; + FLAC__IOCallback_Tell tell; + FLAC__IOCallback_Eof eof; + FLAC__IOCallback_Close close; +} FLAC__IOCallbacks; + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/export.h b/deps/flac-1.3.2/include/FLAC/export.h new file mode 100644 index 0000000..d52f0bb --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/export.h @@ -0,0 +1,97 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__EXPORT_H +#define FLAC__EXPORT_H + +/** \file include/FLAC/export.h + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * See the \link flac_export export \endlink module. + */ + +/** \defgroup flac_export FLAC/export.h: export symbols + * \ingroup flac + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * If you are compiling with MSVC and will link to the static library + * (libFLAC.lib) you should define FLAC__NO_DLL in your project to + * make sure the symbols are exported properly. + * + * \{ + */ + +#if defined(FLAC__NO_DLL) +#define FLAC_API + +#elif defined(_MSC_VER) +#ifdef FLAC_API_EXPORTS +#define FLAC_API __declspec(dllexport) +#else +#define FLAC_API __declspec(dllimport) +#endif + +#elif defined(FLAC__USE_VISIBILITY_ATTR) +#define FLAC_API __attribute__ ((visibility ("default"))) + +#else +#define FLAC_API + +#endif + +/** These #defines will mirror the libtool-based library version number, see + * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning + */ +#define FLAC_API_VERSION_CURRENT 11 +#define FLAC_API_VERSION_REVISION 0 /**< see above */ +#define FLAC_API_VERSION_AGE 3 /**< see above */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */ +extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC; + +#ifdef __cplusplus +} +#endif + +/* \} */ + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/format.h b/deps/flac-1.3.2/include/FLAC/format.h new file mode 100644 index 0000000..c087d4a --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/format.h @@ -0,0 +1,1025 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__FORMAT_H +#define FLAC__FORMAT_H + +#include "export.h" +#include "ordinals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file include/FLAC/format.h + * + * \brief + * This module contains structure definitions for the representation + * of FLAC format components in memory. These are the basic + * structures used by the rest of the interfaces. + * + * See the detailed documentation in the + * \link flac_format format \endlink module. + */ + +/** \defgroup flac_format FLAC/format.h: format components + * \ingroup flac + * + * \brief + * This module contains structure definitions for the representation + * of FLAC format components in memory. These are the basic + * structures used by the rest of the interfaces. + * + * First, you should be familiar with the + * <A HREF="../format.html">FLAC format</A>. Many of the values here + * follow directly from the specification. As a user of libFLAC, the + * interesting parts really are the structures that describe the frame + * header and metadata blocks. + * + * The format structures here are very primitive, designed to store + * information in an efficient way. Reading information from the + * structures is easy but creating or modifying them directly is + * more complex. For the most part, as a user of a library, editing + * is not necessary; however, for metadata blocks it is, so there are + * convenience functions provided in the \link flac_metadata metadata + * module \endlink to simplify the manipulation of metadata blocks. + * + * \note + * It's not the best convention, but symbols ending in _LEN are in bits + * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of + * global variables because they are usually used when declaring byte + * arrays and some compilers require compile-time knowledge of array + * sizes when declared on the stack. + * + * \{ + */ + + +/* + Most of the values described in this file are defined by the FLAC + format specification. There is nothing to tune here. +*/ + +/** The largest legal metadata type code. */ +#define FLAC__MAX_METADATA_TYPE_CODE (126u) + +/** The minimum block size, in samples, permitted by the format. */ +#define FLAC__MIN_BLOCK_SIZE (16u) + +/** The maximum block size, in samples, permitted by the format. */ +#define FLAC__MAX_BLOCK_SIZE (65535u) + +/** The maximum block size, in samples, permitted by the FLAC subset for + * sample rates up to 48kHz. */ +#define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u) + +/** The maximum number of channels permitted by the format. */ +#define FLAC__MAX_CHANNELS (8u) + +/** The minimum sample resolution permitted by the format. */ +#define FLAC__MIN_BITS_PER_SAMPLE (4u) + +/** The maximum sample resolution permitted by the format. */ +#define FLAC__MAX_BITS_PER_SAMPLE (32u) + +/** The maximum sample resolution permitted by libFLAC. + * + * \warning + * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, + * the reference encoder/decoder is currently limited to 24 bits because + * of prevalent 32-bit math, so make sure and use this value when + * appropriate. + */ +#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) + +/** The maximum sample rate permitted by the format. The value is + * ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A> + * as to why. + */ +#define FLAC__MAX_SAMPLE_RATE (655350u) + +/** The maximum LPC order permitted by the format. */ +#define FLAC__MAX_LPC_ORDER (32u) + +/** The maximum LPC order permitted by the FLAC subset for sample rates + * up to 48kHz. */ +#define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u) + +/** The minimum quantized linear predictor coefficient precision + * permitted by the format. + */ +#define FLAC__MIN_QLP_COEFF_PRECISION (5u) + +/** The maximum quantized linear predictor coefficient precision + * permitted by the format. + */ +#define FLAC__MAX_QLP_COEFF_PRECISION (15u) + +/** The maximum order of the fixed predictors permitted by the format. */ +#define FLAC__MAX_FIXED_ORDER (4u) + +/** The maximum Rice partition order permitted by the format. */ +#define FLAC__MAX_RICE_PARTITION_ORDER (15u) + +/** The maximum Rice partition order permitted by the FLAC Subset. */ +#define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u) + +/** The version string of the release, stamped onto the libraries and binaries. + * + * \note + * This does not correspond to the shared library version number, which + * is used to determine binary compatibility. + */ +extern FLAC_API const char *FLAC__VERSION_STRING; + +/** The vendor string inserted by the encoder into the VORBIS_COMMENT block. + * This is a NUL-terminated ASCII string; when inserted into the + * VORBIS_COMMENT the trailing null is stripped. + */ +extern FLAC_API const char *FLAC__VENDOR_STRING; + +/** The byte string representation of the beginning of a FLAC stream. */ +extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */ + +/** The 32-bit integer big-endian representation of the beginning of + * a FLAC stream. + */ +extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */ + +/** The length of the FLAC signature in bits. */ +extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */ + +/** The length of the FLAC signature in bytes. */ +#define FLAC__STREAM_SYNC_LENGTH (4u) + + +/***************************************************************************** + * + * Subframe structures + * + *****************************************************************************/ + +/*****************************************************************************/ + +/** An enumeration of the available entropy coding methods. */ +typedef enum { + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0, + /**< Residual is coded by partitioning into contexts, each with it's own + * 4-bit Rice parameter. */ + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 + /**< Residual is coded by partitioning into contexts, each with it's own + * 5-bit Rice parameter. */ +} FLAC__EntropyCodingMethodType; + +/** Maps a FLAC__EntropyCodingMethodType to a C string. + * + * Using a FLAC__EntropyCodingMethodType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[]; + + +/** Contents of a Rice partitioned residual + */ +typedef struct { + + unsigned *parameters; + /**< The Rice parameters for each context. */ + + unsigned *raw_bits; + /**< Widths for escape-coded partitions. Will be non-zero for escaped + * partitions and zero for unescaped partitions. + */ + + unsigned capacity_by_order; + /**< The capacity of the \a parameters and \a raw_bits arrays + * specified as an order, i.e. the number of array elements + * allocated is 2 ^ \a capacity_by_order. + */ +} FLAC__EntropyCodingMethod_PartitionedRiceContents; + +/** Header for a Rice partitioned residual. (c.f. <A HREF="../format.html#partitioned_rice">format specification</A>) + */ +typedef struct { + + unsigned order; + /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ + + const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; + /**< The context's Rice parameters and/or raw bits. */ + +} FLAC__EntropyCodingMethod_PartitionedRice; + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */ + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; +/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER; +/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ + +/** Header for the entropy coding method. (c.f. <A HREF="../format.html#residual">format specification</A>) + */ +typedef struct { + FLAC__EntropyCodingMethodType type; + union { + FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; + } data; +} FLAC__EntropyCodingMethod; + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */ + +/*****************************************************************************/ + +/** An enumeration of the available subframe types. */ +typedef enum { + FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ + FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ + FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ + FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ +} FLAC__SubframeType; + +/** Maps a FLAC__SubframeType to a C string. + * + * Using a FLAC__SubframeType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__SubframeTypeString[]; + + +/** CONSTANT subframe. (c.f. <A HREF="../format.html#subframe_constant">format specification</A>) + */ +typedef struct { + FLAC__int32 value; /**< The constant signal value. */ +} FLAC__Subframe_Constant; + + +/** VERBATIM subframe. (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>) + */ +typedef struct { + const FLAC__int32 *data; /**< A pointer to verbatim signal. */ +} FLAC__Subframe_Verbatim; + + +/** FIXED subframe. (c.f. <A HREF="../format.html#subframe_fixed">format specification</A>) + */ +typedef struct { + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ + + unsigned order; + /**< The polynomial order. */ + + FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ + + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ +} FLAC__Subframe_Fixed; + + +/** LPC subframe. (c.f. <A HREF="../format.html#subframe_lpc">format specification</A>) + */ +typedef struct { + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ + + unsigned order; + /**< The FIR order. */ + + unsigned qlp_coeff_precision; + /**< Quantized FIR filter coefficient precision in bits. */ + + int quantization_level; + /**< The qlp coeff shift needed. */ + + FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; + /**< FIR filter coefficients. */ + + FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ + + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ +} FLAC__Subframe_LPC; + +extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ + + +/** FLAC subframe structure. (c.f. <A HREF="../format.html#subframe">format specification</A>) + */ +typedef struct { + FLAC__SubframeType type; + union { + FLAC__Subframe_Constant constant; + FLAC__Subframe_Fixed fixed; + FLAC__Subframe_LPC lpc; + FLAC__Subframe_Verbatim verbatim; + } data; + unsigned wasted_bits; +} FLAC__Subframe; + +/** == 1 (bit) + * + * This used to be a zero-padding bit (hence the name + * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a + * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1 + * to mean something else. + */ +extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */ +extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */ + +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /**< = 0x00 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /**< = 0x02 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /**< = 0x10 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = 0x40 */ + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Frame structures + * + *****************************************************************************/ + +/** An enumeration of the available channel assignments. */ +typedef enum { + FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ + FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ +} FLAC__ChannelAssignment; + +/** Maps a FLAC__ChannelAssignment to a C string. + * + * Using a FLAC__ChannelAssignment as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__ChannelAssignmentString[]; + +/** An enumeration of the possible frame numbering methods. */ +typedef enum { + FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ + FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ +} FLAC__FrameNumberType; + +/** Maps a FLAC__FrameNumberType to a C string. + * + * Using a FLAC__FrameNumberType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; + + +/** FLAC frame header structure. (c.f. <A HREF="../format.html#frame_header">format specification</A>) + */ +typedef struct { + unsigned blocksize; + /**< The number of samples per subframe. */ + + unsigned sample_rate; + /**< The sample rate in Hz. */ + + unsigned channels; + /**< The number of channels (== number of subframes). */ + + FLAC__ChannelAssignment channel_assignment; + /**< The channel assignment for the frame. */ + + unsigned bits_per_sample; + /**< The sample resolution. */ + + FLAC__FrameNumberType number_type; + /**< The numbering scheme used for the frame. As a convenience, the + * decoder will always convert a frame number to a sample number because + * the rules are complex. */ + + union { + FLAC__uint32 frame_number; + FLAC__uint64 sample_number; + } number; + /**< The frame number or sample number of first sample in frame; + * use the \a number_type value to determine which to use. */ + + FLAC__uint8 crc; + /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) + * of the raw frame header bytes, meaning everything before the CRC byte + * including the sync code. + */ +} FLAC__FrameHeader; + +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ + + +/** FLAC frame footer structure. (c.f. <A HREF="../format.html#frame_footer">format specification</A>) + */ +typedef struct { + FLAC__uint16 crc; + /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with + * 0) of the bytes before the crc, back to and including the frame header + * sync code. + */ +} FLAC__FrameFooter; + +extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ + + +/** FLAC frame structure. (c.f. <A HREF="../format.html#frame">format specification</A>) + */ +typedef struct { + FLAC__FrameHeader header; + FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; + FLAC__FrameFooter footer; +} FLAC__Frame; + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Meta-data structures + * + *****************************************************************************/ + +/** An enumeration of the available metadata block types. */ +typedef enum { + + FLAC__METADATA_TYPE_STREAMINFO = 0, + /**< <A HREF="../format.html#metadata_block_streaminfo">STREAMINFO</A> block */ + + FLAC__METADATA_TYPE_PADDING = 1, + /**< <A HREF="../format.html#metadata_block_padding">PADDING</A> block */ + + FLAC__METADATA_TYPE_APPLICATION = 2, + /**< <A HREF="../format.html#metadata_block_application">APPLICATION</A> block */ + + FLAC__METADATA_TYPE_SEEKTABLE = 3, + /**< <A HREF="../format.html#metadata_block_seektable">SEEKTABLE</A> block */ + + FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, + /**< <A HREF="../format.html#metadata_block_vorbis_comment">VORBISCOMMENT</A> block (a.k.a. FLAC tags) */ + + FLAC__METADATA_TYPE_CUESHEET = 5, + /**< <A HREF="../format.html#metadata_block_cuesheet">CUESHEET</A> block */ + + FLAC__METADATA_TYPE_PICTURE = 6, + /**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */ + + FLAC__METADATA_TYPE_UNDEFINED = 7, + /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ + + FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE, + /**< No type will ever be greater than this. There is not enough room in the protocol block. */ +} FLAC__MetadataType; + +/** Maps a FLAC__MetadataType to a C string. + * + * Using a FLAC__MetadataType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__MetadataTypeString[]; + + +/** FLAC STREAMINFO structure. (c.f. <A HREF="../format.html#metadata_block_streaminfo">format specification</A>) + */ +typedef struct { + unsigned min_blocksize, max_blocksize; + unsigned min_framesize, max_framesize; + unsigned sample_rate; + unsigned channels; + unsigned bits_per_sample; + FLAC__uint64 total_samples; + FLAC__byte md5sum[16]; +} FLAC__StreamMetadata_StreamInfo; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */ + +/** The total stream length of the STREAMINFO block in bytes. */ +#define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) + +/** FLAC PADDING structure. (c.f. <A HREF="../format.html#metadata_block_padding">format specification</A>) + */ +typedef struct { + int dummy; + /**< Conceptually this is an empty struct since we don't store the + * padding bytes. Empty structs are not allowed by some C compilers, + * hence the dummy. + */ +} FLAC__StreamMetadata_Padding; + + +/** FLAC APPLICATION structure. (c.f. <A HREF="../format.html#metadata_block_application">format specification</A>) + */ +typedef struct { + FLAC__byte id[4]; + FLAC__byte *data; +} FLAC__StreamMetadata_Application; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ + +/** SeekPoint structure used in SEEKTABLE blocks. (c.f. <A HREF="../format.html#seekpoint">format specification</A>) + */ +typedef struct { + FLAC__uint64 sample_number; + /**< The sample number of the target frame. */ + + FLAC__uint64 stream_offset; + /**< The offset, in bytes, of the target frame with respect to + * beginning of the first frame. */ + + unsigned frame_samples; + /**< The number of samples in the target frame. */ +} FLAC__StreamMetadata_SeekPoint; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */ + +/** The total stream length of a seek point in bytes. */ +#define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u) + +/** The value used in the \a sample_number field of + * FLAC__StreamMetadataSeekPoint used to indicate a placeholder + * point (== 0xffffffffffffffff). + */ +extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + + +/** FLAC SEEKTABLE structure. (c.f. <A HREF="../format.html#metadata_block_seektable">format specification</A>) + * + * \note From the format specification: + * - The seek points must be sorted by ascending sample number. + * - Each seek point's sample number must be the first sample of the + * target frame. + * - Each seek point's sample number must be unique within the table. + * - Existence of a SEEKTABLE block implies a correct setting of + * total_samples in the stream_info block. + * - Behavior is undefined when more than one SEEKTABLE block is + * present in a stream. + */ +typedef struct { + unsigned num_points; + FLAC__StreamMetadata_SeekPoint *points; +} FLAC__StreamMetadata_SeekTable; + + +/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>) + * + * For convenience, the APIs maintain a trailing NUL character at the end of + * \a entry which is not counted toward \a length, i.e. + * \code strlen(entry) == length \endcode + */ +typedef struct { + FLAC__uint32 length; + FLAC__byte *entry; +} FLAC__StreamMetadata_VorbisComment_Entry; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ + + +/** FLAC VORBIS_COMMENT structure. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>) + */ +typedef struct { + FLAC__StreamMetadata_VorbisComment_Entry vendor_string; + FLAC__uint32 num_comments; + FLAC__StreamMetadata_VorbisComment_Entry *comments; +} FLAC__StreamMetadata_VorbisComment; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */ + + +/** FLAC CUESHEET track index structure. (See the + * <A HREF="../format.html#cuesheet_track_index">format specification</A> for + * the full description of each field.) + */ +typedef struct { + FLAC__uint64 offset; + /**< Offset in samples, relative to the track offset, of the index + * point. + */ + + FLAC__byte number; + /**< The index point number. */ +} FLAC__StreamMetadata_CueSheet_Index; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */ + + +/** FLAC CUESHEET track structure. (See the + * <A HREF="../format.html#cuesheet_track">format specification</A> for + * the full description of each field.) + */ +typedef struct { + FLAC__uint64 offset; + /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ + + FLAC__byte number; + /**< The track number. */ + + char isrc[13]; + /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */ + + unsigned type:1; + /**< The track type: 0 for audio, 1 for non-audio. */ + + unsigned pre_emphasis:1; + /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ + + FLAC__byte num_indices; + /**< The number of track index points. */ + + FLAC__StreamMetadata_CueSheet_Index *indices; + /**< NULL if num_indices == 0, else pointer to array of index points. */ + +} FLAC__StreamMetadata_CueSheet_Track; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */ + + +/** FLAC CUESHEET structure. (See the + * <A HREF="../format.html#metadata_block_cuesheet">format specification</A> + * for the full description of each field.) + */ +typedef struct { + char media_catalog_number[129]; + /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In + * general, the media catalog number may be 0 to 128 bytes long; any + * unused characters should be right-padded with NUL characters. + */ + + FLAC__uint64 lead_in; + /**< The number of lead-in samples. */ + + FLAC__bool is_cd; + /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */ + + unsigned num_tracks; + /**< The number of tracks. */ + + FLAC__StreamMetadata_CueSheet_Track *tracks; + /**< NULL if num_tracks == 0, else pointer to array of tracks. */ + +} FLAC__StreamMetadata_CueSheet; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */ + + +/** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */ +typedef enum { + FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */ + FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */ + FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */ + FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED +} FLAC__StreamMetadata_Picture_Type; + +/** Maps a FLAC__StreamMetadata_Picture_Type to a C string. + * + * Using a FLAC__StreamMetadata_Picture_Type as the index to this array + * will give the string equivalent. The contents should not be + * modified. + */ +extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; + +/** FLAC PICTURE structure. (See the + * <A HREF="../format.html#metadata_block_picture">format specification</A> + * for the full description of each field.) + */ +typedef struct { + FLAC__StreamMetadata_Picture_Type type; + /**< The kind of picture stored. */ + + char *mime_type; + /**< Picture data's MIME type, in ASCII printable characters + * 0x20-0x7e, NUL terminated. For best compatibility with players, + * use picture data of MIME type \c image/jpeg or \c image/png. A + * MIME type of '-->' is also allowed, in which case the picture + * data should be a complete URL. In file storage, the MIME type is + * stored as a 32-bit length followed by the ASCII string with no NUL + * terminator, but is converted to a plain C string in this structure + * for convenience. + */ + + FLAC__byte *description; + /**< Picture's description in UTF-8, NUL terminated. In file storage, + * the description is stored as a 32-bit length followed by the UTF-8 + * string with no NUL terminator, but is converted to a plain C string + * in this structure for convenience. + */ + + FLAC__uint32 width; + /**< Picture's width in pixels. */ + + FLAC__uint32 height; + /**< Picture's height in pixels. */ + + FLAC__uint32 depth; + /**< Picture's color depth in bits-per-pixel. */ + + FLAC__uint32 colors; + /**< For indexed palettes (like GIF), picture's number of colors (the + * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth). + */ + + FLAC__uint32 data_length; + /**< Length of binary picture data in bytes. */ + + FLAC__byte *data; + /**< Binary picture data. */ + +} FLAC__StreamMetadata_Picture; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /**< == 32 (bits) */ + + +/** Structure that is used when a metadata block of unknown type is loaded. + * The contents are opaque. The structure is used only internally to + * correctly handle unknown metadata. + */ +typedef struct { + FLAC__byte *data; +} FLAC__StreamMetadata_Unknown; + + +/** FLAC metadata block structure. (c.f. <A HREF="../format.html#metadata_block">format specification</A>) + */ +typedef struct { + FLAC__MetadataType type; + /**< The type of the metadata block; used determine which member of the + * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED + * then \a data.unknown must be used. */ + + FLAC__bool is_last; + /**< \c true if this metadata block is the last, else \a false */ + + unsigned length; + /**< Length, in bytes, of the block data as it appears in the stream. */ + + union { + FLAC__StreamMetadata_StreamInfo stream_info; + FLAC__StreamMetadata_Padding padding; + FLAC__StreamMetadata_Application application; + FLAC__StreamMetadata_SeekTable seek_table; + FLAC__StreamMetadata_VorbisComment vorbis_comment; + FLAC__StreamMetadata_CueSheet cue_sheet; + FLAC__StreamMetadata_Picture picture; + FLAC__StreamMetadata_Unknown unknown; + } data; + /**< Polymorphic block data; use the \a type value to determine which + * to use. */ +} FLAC__StreamMetadata; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */ + +/** The total stream length of a metadata block header in bytes. */ +#define FLAC__STREAM_METADATA_HEADER_LENGTH (4u) + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Utility functions + * + *****************************************************************************/ + +/** Tests that a sample rate is valid for FLAC. + * + * \param sample_rate The sample rate to test for compliance. + * \retval FLAC__bool + * \c true if the given sample rate conforms to the specification, else + * \c false. + */ +FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); + +/** Tests that a blocksize at the given sample rate is valid for the FLAC + * subset. + * + * \param blocksize The blocksize to test for compliance. + * \param sample_rate The sample rate is needed, since the valid subset + * blocksize depends on the sample rate. + * \retval FLAC__bool + * \c true if the given blocksize conforms to the specification for the + * subset at the given sample rate, else \c false. + */ +FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate); + +/** Tests that a sample rate is valid for the FLAC subset. The subset rules + * for valid sample rates are slightly more complex since the rate has to + * be expressible completely in the frame header. + * + * \param sample_rate The sample rate to test for compliance. + * \retval FLAC__bool + * \c true if the given sample rate conforms to the specification for the + * subset, else \c false. + */ +FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate); + +/** Check a Vorbis comment entry name to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment names must be composed only of characters from + * [0x20-0x3C,0x3E-0x7D]. + * + * \param name A NUL-terminated string to be checked. + * \assert + * \code name != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name); + +/** Check a Vorbis comment entry value to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment values must be valid UTF-8 sequences. + * + * \param value A string to be checked. + * \param length A the length of \a value in bytes. May be + * \c (unsigned)(-1) to indicate that \a value is a plain + * UTF-8 NUL-terminated string. + * \assert + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length); + +/** Check a Vorbis comment entry to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment entries must be of the form 'name=value', and 'name' and + * 'value' must be legal according to + * FLAC__format_vorbiscomment_entry_name_is_legal() and + * FLAC__format_vorbiscomment_entry_value_is_legal() respectively. + * + * \param entry An entry to be checked. + * \param length The length of \a entry in bytes. + * \assert + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length); + +/** Check a seek table to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * seek table. + * + * \param seek_table A pointer to a seek table to be checked. + * \assert + * \code seek_table != NULL \endcode + * \retval FLAC__bool + * \c false if seek table is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table); + +/** Sort a seek table's seek points according to the format specification. + * This includes a "unique-ification" step to remove duplicates, i.e. + * seek points with identical \a sample_number values. Duplicate seek + * points are converted into placeholder points and sorted to the end of + * the table. + * + * \param seek_table A pointer to a seek table to be sorted. + * \assert + * \code seek_table != NULL \endcode + * \retval unsigned + * The number of duplicate seek points converted into placeholders. + */ +FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table); + +/** Check a cue sheet to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * cue sheet. + * + * \param cue_sheet A pointer to an existing cue sheet to be checked. + * \param check_cd_da_subset If \c true, check CUESHEET against more + * stringent requirements for a CD-DA (audio) disc. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code cue_sheet != NULL \endcode + * \retval FLAC__bool + * \c false if cue sheet is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation); + +/** Check picture data to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * PICTURE block. + * + * \param picture A pointer to existing picture data to be checked. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code picture != NULL \endcode + * \retval FLAC__bool + * \c false if picture data is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/metadata.h b/deps/flac-1.3.2/include/FLAC/metadata.h new file mode 100644 index 0000000..4e18cd6 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/metadata.h @@ -0,0 +1,2182 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__METADATA_H +#define FLAC__METADATA_H + +#include <sys/types.h> /* for off_t */ +#include "export.h" +#include "callback.h" +#include "format.h" + +/* -------------------------------------------------------------------- + (For an example of how all these routines are used, see the source + code for the unit tests in src/test_libFLAC/metadata_*.c, or + metaflac in src/metaflac/) + ------------------------------------------------------------------*/ + +/** \file include/FLAC/metadata.h + * + * \brief + * This module provides functions for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in FLAC files. + * + * See the detailed documentation for each interface in the + * \link flac_metadata metadata \endlink module. + */ + +/** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces + * \ingroup flac + * + * \brief + * This module provides functions for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in native FLAC files. + * Note that currently only the Chain interface (level 2) supports Ogg + * FLAC files, and it is read-only i.e. no writing back changed + * metadata to file. + * + * There are three metadata interfaces of increasing complexity: + * + * Level 0: + * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and + * PICTURE blocks. + * + * Level 1: + * Read-write access to all metadata blocks. This level is write- + * efficient in most cases (more on this below), and uses less memory + * than level 2. + * + * Level 2: + * Read-write access to all metadata blocks. This level is write- + * efficient in all cases, but uses more memory since all metadata for + * the whole file is read into memory and manipulated before writing + * out again. + * + * What do we mean by efficient? Since FLAC metadata appears at the + * beginning of the file, when writing metadata back to a FLAC file + * it is possible to grow or shrink the metadata such that the entire + * file must be rewritten. However, if the size remains the same during + * changes or PADDING blocks are utilized, only the metadata needs to be + * overwritten, which is much faster. + * + * Efficient means the whole file is rewritten at most one time, and only + * when necessary. Level 1 is not efficient only in the case that you + * cause more than one metadata block to grow or shrink beyond what can + * be accomodated by padding. In this case you should probably use level + * 2, which allows you to edit all the metadata for a file in memory and + * write it out all at once. + * + * All levels know how to skip over and not disturb an ID3v2 tag at the + * front of the file. + * + * All levels access files via their filenames. In addition, level 2 + * has additional alternative read and write functions that take an I/O + * handle and callbacks, for situations where access by filename is not + * possible. + * + * In addition to the three interfaces, this module defines functions for + * creating and manipulating various metadata objects in memory. As we see + * from the Format module, FLAC metadata blocks in memory are very primitive + * structures for storing information in an efficient way. Reading + * information from the structures is easy but creating or modifying them + * directly is more complex. The metadata object routines here facilitate + * this by taking care of the consistency and memory management drudgery. + * + * Unless you will be using the level 1 or 2 interfaces to modify existing + * metadata however, you will not probably not need these. + * + * From a dependency standpoint, none of the encoders or decoders require + * the metadata module. This is so that embedded users can strip out the + * metadata module from libFLAC to reduce the size and complexity. + */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface + * \ingroup flac_metadata + * + * \brief + * The level 0 interface consists of individual routines to read the + * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring + * only a filename. + * + * They try to skip any ID3v2 tag at the head of the file. + * + * \{ + */ + +/** Read the STREAMINFO metadata block of the given FLAC file. This function + * will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param streaminfo A pointer to space for the STREAMINFO block. Since + * FLAC__StreamMetadata is a simple structure with no + * memory allocation involved, you pass the address of + * an existing structure. It need not be initialized. + * \assert + * \code filename != NULL \endcode + * \code streaminfo != NULL \endcode + * \retval FLAC__bool + * \c true if a valid STREAMINFO block was read from \a filename. Returns + * \c false if there was a memory allocation error, a file decoder error, + * or the file contained no STREAMINFO block. (A memory allocation error + * is possible because this function must set up a file decoder.) + */ +FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo); + +/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param tags The address where the returned pointer will be + * stored. The \a tags object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \assert + * \code filename != NULL \endcode + * \code tags != NULL \endcode + * \retval FLAC__bool + * \c true if a valid VORBIS_COMMENT block was read from \a filename, + * and \a *tags will be set to the address of the metadata structure. + * Returns \c false if there was a memory allocation error, a file + * decoder error, or the file contained no VORBIS_COMMENT block, and + * \a *tags will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags); + +/** Read the CUESHEET metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param cuesheet The address where the returned pointer will be + * stored. The \a cuesheet object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \assert + * \code filename != NULL \endcode + * \code cuesheet != NULL \endcode + * \retval FLAC__bool + * \c true if a valid CUESHEET block was read from \a filename, + * and \a *cuesheet will be set to the address of the metadata + * structure. Returns \c false if there was a memory allocation + * error, a file decoder error, or the file contained no CUESHEET + * block, and \a *cuesheet will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet); + +/** Read a PICTURE metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * Since there can be more than one PICTURE block in a file, this + * function takes a number of parameters that act as constraints to + * the search. The PICTURE block with the largest area matching all + * the constraints will be returned, or \a *picture will be set to + * \c NULL if there was no such block. + * + * \param filename The path to the FLAC file to read. + * \param picture The address where the returned pointer will be + * stored. The \a picture object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \param type The desired picture type. Use \c -1 to mean + * "any type". + * \param mime_type The desired MIME type, e.g. "image/jpeg". The + * string will be matched exactly. Use \c NULL to + * mean "any MIME type". + * \param description The desired description. The string will be + * matched exactly. Use \c NULL to mean "any + * description". + * \param max_width The maximum width in pixels desired. Use + * \c (unsigned)(-1) to mean "any width". + * \param max_height The maximum height in pixels desired. Use + * \c (unsigned)(-1) to mean "any height". + * \param max_depth The maximum color depth in bits-per-pixel desired. + * Use \c (unsigned)(-1) to mean "any depth". + * \param max_colors The maximum number of colors desired. Use + * \c (unsigned)(-1) to mean "any number of colors". + * \assert + * \code filename != NULL \endcode + * \code picture != NULL \endcode + * \retval FLAC__bool + * \c true if a valid PICTURE block was read from \a filename, + * and \a *picture will be set to the address of the metadata + * structure. Returns \c false if there was a memory allocation + * error, a file decoder error, or the file contained no PICTURE + * block, and \a *picture will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); + +/* \} */ + + +/** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface + * \ingroup flac_metadata + * + * \brief + * The level 1 interface provides read-write access to FLAC file metadata and + * operates directly on the FLAC file. + * + * The general usage of this interface is: + * + * - Create an iterator using FLAC__metadata_simple_iterator_new() + * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check + * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to + * see if the file is writable, or only read access is allowed. + * - Use FLAC__metadata_simple_iterator_next() and + * FLAC__metadata_simple_iterator_prev() to traverse the blocks. + * This is does not read the actual blocks themselves. + * FLAC__metadata_simple_iterator_next() is relatively fast. + * FLAC__metadata_simple_iterator_prev() is slower since it needs to search + * forward from the front of the file. + * - Use FLAC__metadata_simple_iterator_get_block_type() or + * FLAC__metadata_simple_iterator_get_block() to access the actual data at + * the current iterator position. The returned object is yours to modify + * and free. + * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block + * back. You must have write permission to the original file. Make sure to + * read the whole comment to FLAC__metadata_simple_iterator_set_block() + * below. + * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. + * Use the object creation functions from + * \link flac_metadata_object here \endlink to generate new objects. + * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block + * currently referred to by the iterator, or replace it with padding. + * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when + * finished. + * + * \note + * The FLAC file remains open the whole time between + * FLAC__metadata_simple_iterator_init() and + * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering + * the file during this time. + * + * \note + * Do not modify the \a is_last, \a length, or \a type fields of returned + * FLAC__StreamMetadata objects. These are managed automatically. + * + * \note + * If any of the modification functions + * (FLAC__metadata_simple_iterator_set_block(), + * FLAC__metadata_simple_iterator_delete_block(), + * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, + * you should delete the iterator as it may no longer be valid. + * + * \{ + */ + +struct FLAC__Metadata_SimpleIterator; +/** The opaque structure definition for the level 1 iterator type. + * See the + * \link flac_metadata_level1 metadata level 1 module \endlink + * for a detailed description. + */ +typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator; + +/** Status type for FLAC__Metadata_SimpleIterator. + * + * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). + */ +typedef enum { + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, + /**< The iterator is in the normal OK state */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, + /**< The iterator could not open the target file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, + /**< The iterator could not find the FLAC signature at the start of the file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, + /**< The iterator tried to write to a file that was not writable */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, + /**< The iterator encountered input that does not conform to the FLAC metadata specification */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, + /**< The iterator encountered an error while reading the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, + /**< The iterator encountered an error while seeking in the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, + /**< The iterator encountered an error while writing the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, + /**< The iterator encountered an error renaming the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, + /**< The iterator encountered an error removing the temporary file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR + /**< The caller violated an assertion or an unexpected error occurred */ + +} FLAC__Metadata_SimpleIteratorStatus; + +/** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string. + * + * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[]; + + +/** Create a new iterator instance. + * + * \retval FLAC__Metadata_SimpleIterator* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void); + +/** Free an iterator instance. Deletes the object pointed to by \a iterator. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + */ +FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator); + +/** Get the current status of the iterator. Call this after a function + * returns \c false to get the reason for the error. Also resets the status + * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + * \retval FLAC__Metadata_SimpleIteratorStatus + * The current status of the iterator. + */ +FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); + +/** Initialize the iterator to point to the first metadata block in the + * given FLAC file. + * + * \param iterator A pointer to an existing iterator. + * \param filename The path to the FLAC file. + * \param read_only If \c true, the FLAC file will be opened + * in read-only mode; if \c false, the FLAC + * file will be opened for edit even if no + * edits are performed. + * \param preserve_file_stats If \c true, the owner and modification + * time will be preserved even if the FLAC + * file is written to. + * \assert + * \code iterator != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c false if a memory allocation error occurs, the file can't be + * opened, or another error occurs, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); + +/** Returns \c true if the FLAC file is writable. If \c false, calls to + * FLAC__metadata_simple_iterator_set_block() and + * FLAC__metadata_simple_iterator_insert_block_after() will fail. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + * \retval FLAC__bool + * See above. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator); + +/** Moves the iterator forward one metadata block, returning \c false if + * already at the end. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c false if already at the last metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator); + +/** Moves the iterator backward one metadata block, returning \c false if + * already at the beginning. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c false if already at the first metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); + +/** Returns a flag telling if the current metadata block is the last. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the current metadata block is the last in the file, + * else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the offset of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval off_t + * The offset of the metadata block at the current iterator position. + * This is the byte offset relative to the beginning of the file of + * the current metadata block's header. + */ +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the type of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__MetadataType + * The type of the metadata block at the current iterator position. + */ +FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the length of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval unsigned + * The length of the metadata block at the current iterator position. + * The is same length as that in the + * <a href="http://xiph.org/flac/format.html#metadata_block_header">metadata block header</a>, + * i.e. the length of the metadata body that follows the header. + */ +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the application ID of the \c APPLICATION block at the current + * position. This avoids reading the actual block data which can save + * time for large blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \param id A pointer to a buffer of at least \c 4 bytes where + * the ID will be stored. + * \assert + * \code iterator != NULL \endcode + * \code id != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the ID was successfully read, else \c false, in which + * case you should check FLAC__metadata_simple_iterator_status() to + * find out why. If the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the + * current metadata block is not an \c APPLICATION block. Otherwise + * if the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error + * occurred and the iterator can no longer be used. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id); + +/** Get the metadata block at the current position. You can modify the + * block but must use FLAC__metadata_simple_iterator_set_block() to + * write it back to the FLAC file. + * + * You must call FLAC__metadata_object_delete() on the returned object + * when you are finished with it. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__StreamMetadata* + * The current metadata block, or \c NULL if there was a memory + * allocation error. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); + +/** Write a block back to the FLAC file. This function tries to be + * as efficient as possible; how the block is actually written is + * shown by the following: + * + * Existing block is a STREAMINFO block and the new block is a + * STREAMINFO block: the new block is written in place. Make sure + * you know what you're doing when changing the values of a + * STREAMINFO block. + * + * Existing block is a STREAMINFO block and the new block is a + * not a STREAMINFO block: this is an error since the first block + * must be a STREAMINFO block. Returns \c false without altering the + * file. + * + * Existing block is not a STREAMINFO block and the new block is a + * STREAMINFO block: this is an error since there may be only one + * STREAMINFO block. Returns \c false without altering the file. + * + * Existing block and new block are the same length: the existing + * block will be replaced by the new block, written in place. + * + * Existing block is longer than new block: if use_padding is \c true, + * the existing block will be overwritten in place with the new + * block followed by a PADDING block, if possible, to make the total + * size the same as the existing block. Remember that a padding + * block requires at least four bytes so if the difference in size + * between the new block and existing block is less than that, the + * entire file will have to be rewritten, using the new block's + * exact size. If use_padding is \c false, the entire file will be + * rewritten, replacing the existing block by the new block. + * + * Existing block is shorter than new block: if use_padding is \c true, + * the function will try and expand the new block into the following + * PADDING block, if it exists and doing so won't shrink the PADDING + * block to less than 4 bytes. If there is no following PADDING + * block, or it will shrink to less than 4 bytes, or use_padding is + * \c false, the entire file is rewritten, replacing the existing block + * with the new block. Note that in this case any following PADDING + * block is preserved as is. + * + * After writing the block, the iterator will remain in the same + * place, i.e. pointing to the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block The block to set. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); + +/** This is similar to FLAC__metadata_simple_iterator_set_block() + * except that instead of writing over an existing block, it appends + * a block after the existing block. \a use_padding is again used to + * tell the function to try an expand into following padding in an + * attempt to avoid rewriting the entire file. + * + * This function will fail and return \c false if given a STREAMINFO + * block. + * + * After writing the block, the iterator will be pointing to the + * new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block The block to set. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); + +/** Deletes the block at the current position. This will cause the + * entire FLAC file to be rewritten, unless \a use_padding is \c true, + * in which case the block will be replaced by an equal-sized PADDING + * block. The iterator will be left pointing to the block before the + * one just deleted. + * + * You may not delete the STREAMINFO block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding); + +/* \} */ + + +/** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface + * \ingroup flac_metadata + * + * \brief + * The level 2 interface provides read-write access to FLAC file metadata; + * all metadata is read into memory, operated on in memory, and then written + * to file, which is more efficient than level 1 when editing multiple blocks. + * + * Currently Ogg FLAC is supported for read only, via + * FLAC__metadata_chain_read_ogg() but a subsequent + * FLAC__metadata_chain_write() will fail. + * + * The general usage of this interface is: + * + * - Create a new chain using FLAC__metadata_chain_new(). A chain is a + * linked list of FLAC metadata blocks. + * - Read all metadata into the chain from a FLAC file using + * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and + * check the status. + * - Optionally, consolidate the padding using + * FLAC__metadata_chain_merge_padding() or + * FLAC__metadata_chain_sort_padding(). + * - Create a new iterator using FLAC__metadata_iterator_new() + * - Initialize the iterator to point to the first element in the chain + * using FLAC__metadata_iterator_init() + * - Traverse the chain using FLAC__metadata_iterator_next and + * FLAC__metadata_iterator_prev(). + * - Get a block for reading or modification using + * FLAC__metadata_iterator_get_block(). The pointer to the object + * inside the chain is returned, so the block is yours to modify. + * Changes will be reflected in the FLAC file when you write the + * chain. You can also add and delete blocks (see functions below). + * - When done, write out the chain using FLAC__metadata_chain_write(). + * Make sure to read the whole comment to the function below. + * - Delete the chain using FLAC__metadata_chain_delete(). + * + * \note + * Even though the FLAC file is not open while the chain is being + * manipulated, you must not alter the file externally during + * this time. The chain assumes the FLAC file will not change + * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg() + * and FLAC__metadata_chain_write(). + * + * \note + * Do not modify the is_last, length, or type fields of returned + * FLAC__StreamMetadata objects. These are managed automatically. + * + * \note + * The metadata objects returned by FLAC__metadata_iterator_get_block() + * are owned by the chain; do not FLAC__metadata_object_delete() them. + * In the same way, blocks passed to FLAC__metadata_iterator_set_block() + * become owned by the chain and they will be deleted when the chain is + * deleted. + * + * \{ + */ + +struct FLAC__Metadata_Chain; +/** The opaque structure definition for the level 2 chain type. + */ +typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain; + +struct FLAC__Metadata_Iterator; +/** The opaque structure definition for the level 2 iterator type. + */ +typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator; + +typedef enum { + FLAC__METADATA_CHAIN_STATUS_OK = 0, + /**< The chain is in the normal OK state */ + + FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ + + FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, + /**< The chain could not open the target file */ + + FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, + /**< The chain could not find the FLAC signature at the start of the file */ + + FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, + /**< The chain tried to write to a file that was not writable */ + + FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, + /**< The chain encountered input that does not conform to the FLAC metadata specification */ + + FLAC__METADATA_CHAIN_STATUS_READ_ERROR, + /**< The chain encountered an error while reading the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, + /**< The chain encountered an error while seeking in the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, + /**< The chain encountered an error while writing the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, + /**< The chain encountered an error renaming the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, + /**< The chain encountered an error removing the temporary file */ + + FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ + + FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, + /**< The caller violated an assertion or an unexpected error occurred */ + + FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, + /**< One or more of the required callbacks was NULL */ + + FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, + /**< FLAC__metadata_chain_write() was called on a chain read by + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * or + * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile() + * was called on a chain read by + * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Matching read/write methods must always be used. */ + + FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL + /**< FLAC__metadata_chain_write_with_callbacks() was called when the + * chain write requires a tempfile; use + * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. + * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was + * called when the chain write does not require a tempfile; use + * FLAC__metadata_chain_write_with_callbacks() instead. + * Always check FLAC__metadata_chain_check_if_tempfile_needed() + * before writing via callbacks. */ + +} FLAC__Metadata_ChainStatus; + +/** Maps a FLAC__Metadata_ChainStatus to a C string. + * + * Using a FLAC__Metadata_ChainStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[]; + +/*********** FLAC__Metadata_Chain ***********/ + +/** Create a new chain instance. + * + * \retval FLAC__Metadata_Chain* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void); + +/** Free a chain instance. Deletes the object pointed to by \a chain. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); + +/** Get the current status of the chain. Call this after a function + * returns \c false to get the reason for the error. Also resets the + * status to FLAC__METADATA_CHAIN_STATUS_OK. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__Metadata_ChainStatus + * The current status of the chain. + */ +FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); + +/** Read all metadata from a FLAC file into the chain. + * + * \param chain A pointer to an existing chain. + * \param filename The path to the FLAC file to read. + * \assert + * \code chain != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a filename, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); + +/** Read all metadata from an Ogg FLAC file into the chain. + * + * \note Ogg FLAC metadata data writing is not supported yet and + * FLAC__metadata_chain_write() will fail. + * + * \param chain A pointer to an existing chain. + * \param filename The path to the Ogg FLAC file to read. + * \assert + * \code chain != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a filename, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename); + +/** Read all metadata from a FLAC stream into the chain via I/O callbacks. + * + * The \a handle need only be open for reading, but must be seekable. + * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * \param chain A pointer to an existing chain. + * \param handle The I/O handle of the FLAC stream to read. The + * handle will NOT be closed after the metadata is read; + * that is the duty of the caller. + * \param callbacks + * A set of callbacks to use for I/O. The mandatory + * callbacks are \a read, \a seek, and \a tell. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a handle, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks. + * + * The \a handle need only be open for reading, but must be seekable. + * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * \note Ogg FLAC metadata data writing is not supported yet and + * FLAC__metadata_chain_write() will fail. + * + * \param chain A pointer to an existing chain. + * \param handle The I/O handle of the Ogg FLAC stream to read. The + * handle will NOT be closed after the metadata is read; + * that is the duty of the caller. + * \param callbacks + * A set of callbacks to use for I/O. The mandatory + * callbacks are \a read, \a seek, and \a tell. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a handle, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Checks if writing the given chain would require the use of a + * temporary file, or if it could be written in place. + * + * Under certain conditions, padding can be utilized so that writing + * edited metadata back to the FLAC file does not require rewriting the + * entire file. If rewriting is required, then a temporary workfile is + * required. When writing metadata using callbacks, you must check + * this function to know whether to call + * FLAC__metadata_chain_write_with_callbacks() or + * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When + * writing with FLAC__metadata_chain_write(), the temporary file is + * handled internally. + * + * \param chain A pointer to an existing chain. + * \param use_padding + * Whether or not padding will be allowed to be used + * during the write. The value of \a use_padding given + * here must match the value later passed to + * FLAC__metadata_chain_write_with_callbacks() or + * FLAC__metadata_chain_write_with_callbacks_with_tempfile(). + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if writing the current chain would require a tempfile, or + * \c false if metadata can be written in place. + */ +FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding); + +/** Write all metadata out to the FLAC file. This function tries to be as + * efficient as possible; how the metadata is actually written is shown by + * the following: + * + * If the current chain is the same size as the existing metadata, the new + * data is written in place. + * + * If the current chain is longer than the existing metadata, and + * \a use_padding is \c true, and the last block is a PADDING block of + * sufficient length, the function will truncate the final padding block + * so that the overall size of the metadata is the same as the existing + * metadata, and then just rewrite the metadata. Otherwise, if not all of + * the above conditions are met, the entire FLAC file must be rewritten. + * If you want to use padding this way it is a good idea to call + * FLAC__metadata_chain_sort_padding() first so that you have the maximum + * amount of padding to work with, unless you need to preserve ordering + * of the PADDING blocks for some reason. + * + * If the current chain is shorter than the existing metadata, and + * \a use_padding is \c true, and the final block is a PADDING block, the padding + * is extended to make the overall size the same as the existing data. If + * \a use_padding is \c true and the last block is not a PADDING block, a new + * PADDING block is added to the end of the new data to make it the same + * size as the existing data (if possible, see the note to + * FLAC__metadata_simple_iterator_set_block() about the four byte limit) + * and the new data is written in place. If none of the above apply or + * \a use_padding is \c false, the entire FLAC file is rewritten. + * + * If \a preserve_file_stats is \c true, the owner and modification time will + * be preserved even if the FLAC file is written. + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(). + * + * \param chain A pointer to an existing chain. + * \param use_padding See above. + * \param preserve_file_stats See above. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats); + +/** Write all metadata out to a FLAC stream via callbacks. + * + * (See FLAC__metadata_chain_write() for the details on how padding is + * used to write metadata in place if possible.) + * + * The \a handle must be open for updating and be seekable. The + * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" + * for Windows). + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + * \c false. + * + * \param chain A pointer to an existing chain. + * \param use_padding See FLAC__metadata_chain_write() + * \param handle The I/O handle of the FLAC stream to write. The + * handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param callbacks A set of callbacks to use for I/O. The mandatory + * callbacks are \a write and \a seek. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Write all metadata out to a FLAC stream via callbacks. + * + * (See FLAC__metadata_chain_write() for the details on how padding is + * used to write metadata in place if possible.) + * + * This version of the write-with-callbacks function must be used when + * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In + * this function, you must supply an I/O handle corresponding to the + * FLAC file to edit, and a temporary handle to which the new FLAC + * file will be written. It is the caller's job to move this temporary + * FLAC file on top of the original FLAC file to complete the metadata + * edit. + * + * The \a handle must be open for reading and be seekable. The + * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * The \a temp_handle must be open for writing. The + * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" + * for Windows). It should be an empty stream, or at least positioned + * at the start-of-file (in which case it is the caller's duty to + * truncate it on return). + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + * \c true. + * + * \param chain A pointer to an existing chain. + * \param use_padding See FLAC__metadata_chain_write() + * \param handle The I/O handle of the original FLAC stream to read. + * The handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param callbacks A set of callbacks to use for I/O on \a handle. + * The mandatory callbacks are \a read, \a seek, and + * \a eof. + * \param temp_handle The I/O handle of the FLAC stream to write. The + * handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param temp_callbacks + * A set of callbacks to use for I/O on temp_handle. + * The only mandatory callback is \a write. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks); + +/** Merge adjacent PADDING blocks into a single block. + * + * \note This function does not write to the FLAC file, it only + * modifies the chain. + * + * \warning Any iterator on the current chain will become invalid after this + * call. You should delete the iterator and get a new one. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain); + +/** This function will move all PADDING blocks to the end on the metadata, + * then merge them into a single block. + * + * \note This function does not write to the FLAC file, it only + * modifies the chain. + * + * \warning Any iterator on the current chain will become invalid after this + * call. You should delete the iterator and get a new one. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain); + + +/*********** FLAC__Metadata_Iterator ***********/ + +/** Create a new iterator instance. + * + * \retval FLAC__Metadata_Iterator* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void); + +/** Free an iterator instance. Deletes the object pointed to by \a iterator. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + */ +FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator); + +/** Initialize the iterator to point to the first metadata block in the + * given chain. + * + * \param iterator A pointer to an existing iterator. + * \param chain A pointer to an existing and initialized (read) chain. + * \assert + * \code iterator != NULL \endcode + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain); + +/** Moves the iterator forward one metadata block, returning \c false if + * already at the end. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if already at the last metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator); + +/** Moves the iterator backward one metadata block, returning \c false if + * already at the beginning. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if already at the first metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator); + +/** Get the type of the metadata block at the current position. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__MetadataType + * The type of the metadata block at the current iterator position. + */ +FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator); + +/** Get the metadata block at the current position. You can modify + * the block in place but must write the chain before the changes + * are reflected to the FLAC file. You do not need to call + * FLAC__metadata_iterator_set_block() to reflect the changes; + * the pointer returned by FLAC__metadata_iterator_get_block() + * points directly into the chain. + * + * \warning + * Do not call FLAC__metadata_object_delete() on the returned object; + * to delete a block use FLAC__metadata_iterator_delete_block(). + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__StreamMetadata* + * The current metadata block. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator); + +/** Set the metadata block at the current position, replacing the existing + * block. The new block passed in becomes owned by the chain and it will be + * deleted when the chain is deleted. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/** Removes the current block from the chain. If \a replace_with_padding is + * \c true, the block will instead be replaced with a padding block of equal + * size. You can not delete the STREAMINFO block. The iterator will be + * left pointing to the block before the one just "deleted", even if + * \a replace_with_padding is \c true. + * + * \param iterator A pointer to an existing initialized iterator. + * \param replace_with_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, + * otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding); + +/** Insert a new block before the current block. You cannot insert a block + * before the first STREAMINFO block. You cannot insert a STREAMINFO block + * as there can be only one, the one that already exists at the head when you + * read in a chain. The chain takes ownership of the new block and it will be + * deleted when the chain is deleted. The iterator will be left pointing to + * the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block to insert. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/** Insert a new block after the current block. You cannot insert a STREAMINFO + * block as there can be only one, the one that already exists at the head when + * you read in a chain. The chain takes ownership of the new block and it will + * be deleted when the chain is deleted. The iterator will be left pointing to + * the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block to insert. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/* \} */ + + +/** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods + * \ingroup flac_metadata + * + * \brief + * This module contains methods for manipulating FLAC metadata objects. + * + * Since many are variable length we have to be careful about the memory + * management. We decree that all pointers to data in the object are + * owned by the object and memory-managed by the object. + * + * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() + * functions to create all instances. When using the + * FLAC__metadata_object_set_*() functions to set pointers to data, set + * \a copy to \c true to have the function make it's own copy of the data, or + * to \c false to give the object ownership of your data. In the latter case + * your pointer must be freeable by free() and will be free()d when the object + * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as + * the data pointer to a FLAC__metadata_object_set_*() function as long as + * the length argument is 0 and the \a copy argument is \c false. + * + * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function + * will return \c NULL in the case of a memory allocation error, otherwise a new + * object. The FLAC__metadata_object_set_*() functions return \c false in the + * case of a memory allocation error. + * + * We don't have the convenience of C++ here, so note that the library relies + * on you to keep the types straight. In other words, if you pass, for + * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to + * FLAC__metadata_object_application_set_data(), you will get an assertion + * failure. + * + * For convenience the FLAC__metadata_object_vorbiscomment_*() functions + * maintain a trailing NUL on each Vorbis comment entry. This is not counted + * toward the length or stored in the stream, but it can make working with plain + * comments (those that don't contain embedded-NULs in the value) easier. + * Entries passed into these functions have trailing NULs added if missing, and + * returned entries are guaranteed to have a trailing NUL. + * + * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis + * comment entry/name/value will first validate that it complies with the Vorbis + * comment specification and return false if it does not. + * + * There is no need to recalculate the length field on metadata blocks you + * have modified. They will be calculated automatically before they are + * written back to a file. + * + * \{ + */ + + +/** Create a new metadata object instance of the given type. + * + * The object will be "empty"; i.e. values and data pointers will be \c 0, + * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have + * the vendor string set (but zero comments). + * + * Do not pass in a value greater than or equal to + * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're + * doing. + * + * \param type Type of object to create + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error allocating memory or the type code is + * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type); + +/** Create a copy of an existing metadata object. + * + * The copy is a "deep" copy, i.e. dynamically allocated data within the + * object is also copied. The caller takes ownership of the new block and + * is responsible for freeing it with FLAC__metadata_object_delete(). + * + * \param object Pointer to object to copy. + * \assert + * \code object != NULL \endcode + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object); + +/** Free a metadata object. Deletes the object pointed to by \a object. + * + * The delete is a "deep" delete, i.e. dynamically allocated data within the + * object is also deleted. + * + * \param object A pointer to an existing object. + * \assert + * \code object != NULL \endcode + */ +FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object); + +/** Compares two metadata objects. + * + * The compare is "deep", i.e. dynamically allocated data within the + * object is also compared. + * + * \param block1 A pointer to an existing object. + * \param block2 A pointer to an existing object. + * \assert + * \code block1 != NULL \endcode + * \code block2 != NULL \endcode + * \retval FLAC__bool + * \c true if objects are identical, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2); + +/** Sets the application data of an APPLICATION block. + * + * If \a copy is \c true, a copy of the data is stored; otherwise, the object + * takes ownership of the pointer. The existing data will be freed if this + * function is successful, otherwise the original data will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a data if \a copy is \c true. + * + * \param object A pointer to an existing APPLICATION object. + * \param data A pointer to the data to set. + * \param length The length of \a data in bytes. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode + * \code (data != NULL && length > 0) || + * (data == NULL && length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy); + +/** Resize the seekpoint array. + * + * If the size shrinks, elements will truncated; if it grows, new placeholder + * points will be added to the end. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param new_num_points The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || + * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points); + +/** Set a seekpoint in a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \param point The point to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points > point_num \endcode + */ +FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); + +/** Insert a seekpoint into a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \param point The point to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points >= point_num \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); + +/** Delete a seekpoint from a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points > point_num \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num); + +/** Check a seektable to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if seek table is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object); + +/** Append a number of placeholder points to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param num The number of placeholder points to append. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num); + +/** Append a specific seek point template to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param sample_number The sample number of the seek point template. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number); + +/** Append specific seek point templates to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param sample_numbers An array of sample numbers for the seek points. + * \param num The number of seek point templates to append. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num); + +/** Append a set of evenly-spaced seek point templates to the end of a + * seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param num The number of placeholder points to append. + * \param total_samples The total number of samples to be encoded; + * the seekpoints will be spaced approximately + * \a total_samples / \a num samples apart. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code total_samples > 0 \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples); + +/** Append a set of evenly-spaced seek point templates to the end of a + * seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param samples The number of samples apart to space the placeholder + * points. The first point will be at sample \c 0, the + * second at sample \a samples, then 2*\a samples, and + * so on. As long as \a samples and \a total_samples + * are greater than \c 0, there will always be at least + * one seekpoint at sample \c 0. + * \param total_samples The total number of samples to be encoded; + * the seekpoints will be spaced + * \a samples samples apart. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code samples > 0 \endcode + * \code total_samples > 0 \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples); + +/** Sort a seek table's seek points according to the format specification, + * removing duplicates. + * + * \param object A pointer to a seek table to be sorted. + * \param compact If \c false, behaves like FLAC__format_seektable_sort(). + * If \c true, duplicates are deleted and the seek table is + * shrunk appropriately; the number of placeholder points + * present in the seek table will be the same after the call + * as before. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact); + +/** Sets the vendor string in a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The entry to set the vendor string to. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Resize the comment array. + * + * If the size shrinks, elements will truncated; if it grows, new empty + * fields will be added to the end. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param new_num_comments The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || + * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments); + +/** Sets a comment in a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num Index into comment array to set. + * \param entry The entry to set the comment to. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code comment_num < object->data.vorbis_comment.num_comments \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Insert a comment in a VORBIS_COMMENT block at the given index. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num The index at which to insert the comment. The comments + * at and after \a comment_num move right one position. + * To append a comment to the end, set \a comment_num to + * \c object->data.vorbis_comment.num_comments . + * \param entry The comment to insert. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code object->data.vorbis_comment.num_comments >= comment_num \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Appends a comment to a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The comment to insert. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Replaces comments in a VORBIS_COMMENT block with a new one. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * Depending on the value of \a all, either all or just the first comment + * whose field name(s) match the given entry's name will be replaced by the + * given entry. If no comments match, \a entry will simply be appended. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The comment to insert. + * \param all If \c true, all comments whose field name matches + * \a entry's field name will be removed, and \a entry will + * be inserted at the position of the first matching + * comment. If \c false, only the first comment whose + * field name matches \a entry's field name will be + * replaced with \a entry. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy); + +/** Delete a comment in a VORBIS_COMMENT block at the given index. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num The index of the comment to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code object->data.vorbis_comment.num_comments > comment_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num); + +/** Creates a Vorbis comment entry from NUL-terminated name and value strings. + * + * On return, the filled-in \a entry->entry pointer will point to malloc()ed + * memory and shall be owned by the caller. For convenience the entry will + * have a terminating NUL. + * + * \param entry A pointer to a Vorbis comment entry. The entry's + * \c entry pointer should not point to allocated + * memory as it will be overwritten. + * \param field_name The field name in ASCII, \c NUL terminated. + * \param field_value The field value in UTF-8, \c NUL terminated. + * \assert + * \code entry != NULL \endcode + * \code field_name != NULL \endcode + * \code field_value != NULL \endcode + * \retval FLAC__bool + * \c false if malloc() fails, or if \a field_name or \a field_value does + * not comply with the Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value); + +/** Splits a Vorbis comment entry into NUL-terminated name and value strings. + * + * The returned pointers to name and value will be allocated by malloc() + * and shall be owned by the caller. + * + * \param entry An existing Vorbis comment entry. + * \param field_name The address of where the returned pointer to the + * field name will be stored. + * \param field_value The address of where the returned pointer to the + * field value will be stored. + * \assert + * \code (entry.entry != NULL && entry.length > 0) \endcode + * \code memchr(entry.entry, '=', entry.length) != NULL \endcode + * \code field_name != NULL \endcode + * \code field_value != NULL \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value); + +/** Check if the given Vorbis comment entry's field name matches the given + * field name. + * + * \param entry An existing Vorbis comment entry. + * \param field_name The field name to check. + * \param field_name_length The length of \a field_name, not including the + * terminating \c NUL. + * \assert + * \code (entry.entry != NULL && entry.length > 0) \endcode + * \retval FLAC__bool + * \c true if the field names match, else \c false + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length); + +/** Find a Vorbis comment with the given field name. + * + * The search begins at entry number \a offset; use an offset of 0 to + * search from the beginning of the comment array. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param offset The offset into the comment array from where to start + * the search. + * \param field_name The field name of the comment to find. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code field_name != NULL \endcode + * \retval int + * The offset in the comment array of the first comment whose field + * name matches \a field_name, or \c -1 if no match was found. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name); + +/** Remove first Vorbis comment matching the given field name. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param field_name The field name of comment to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \retval int + * \c -1 for memory allocation error, \c 0 for no matching entries, + * \c 1 for one matching entry deleted. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name); + +/** Remove all Vorbis comments matching the given field name. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param field_name The field name of comments to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \retval int + * \c -1 for memory allocation error, \c 0 for no matching entries, + * else the number of matching entries deleted. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name); + +/** Create a new CUESHEET track instance. + * + * The object will be "empty"; i.e. values and data pointers will be \c 0. + * + * \retval FLAC__StreamMetadata_CueSheet_Track* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void); + +/** Create a copy of an existing CUESHEET track object. + * + * The copy is a "deep" copy, i.e. dynamically allocated data within the + * object is also copied. The caller takes ownership of the new object and + * is responsible for freeing it with + * FLAC__metadata_object_cuesheet_track_delete(). + * + * \param object Pointer to object to copy. + * \assert + * \code object != NULL \endcode + * \retval FLAC__StreamMetadata_CueSheet_Track* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object); + +/** Delete a CUESHEET track object + * + * \param object A pointer to an existing CUESHEET track object. + * \assert + * \code object != NULL \endcode + */ +FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object); + +/** Resize a track's index point array. + * + * If the size shrinks, elements will truncated; if it grows, new blank + * indices will be added to the end. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param new_num_indices The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || + * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices); + +/** Insert an index point in a CUESHEET track at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param index_num The index into the track's index array at which to + * insert the index point. NOTE: this is not necessarily + * the same as the index point's \a number field. The + * indices at and after \a index_num move right one + * position. To append an index point to the end, set + * \a index_num to + * \c object->data.cue_sheet.tracks[track_num].num_indices . + * \param index The index point to insert. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index); + +/** Insert a blank index point in a CUESHEET track at the given index. + * + * A blank index point is one in which all field values are zero. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param index_num The index into the track's index array at which to + * insert the index point. NOTE: this is not necessarily + * the same as the index point's \a number field. The + * indices at and after \a index_num move right one + * position. To append an index point to the end, set + * \a index_num to + * \c object->data.cue_sheet.tracks[track_num].num_indices . + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); + +/** Delete an index point in a CUESHEET track at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index into the track array of the track to + * modify. NOTE: this is not necessarily the same + * as the track's \a number field. + * \param index_num The index into the track's index array of the index + * to delete. NOTE: this is not necessarily the same + * as the index's \a number field. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); + +/** Resize the track array. + * + * If the size shrinks, elements will truncated; if it grows, new blank + * tracks will be added to the end. + * + * \param object A pointer to an existing CUESHEET object. + * \param new_num_tracks The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || + * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks); + +/** Sets a track in a CUESHEET block. + * + * If \a copy is \c true, a copy of the track is stored; otherwise, the object + * takes ownership of the \a track pointer. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num Index into track array to set. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param track The track to set the track to. You may safely pass in + * a const pointer if \a copy is \c true. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code track_num < object->data.cue_sheet.num_tracks \endcode + * \code (track->indices != NULL && track->num_indices > 0) || + * (track->indices == NULL && track->num_indices == 0) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); + +/** Insert a track in a CUESHEET block at the given index. + * + * If \a copy is \c true, a copy of the track is stored; otherwise, the object + * takes ownership of the \a track pointer. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index at which to insert the track. NOTE: this + * is not necessarily the same as the track's \a number + * field. The tracks at and after \a track_num move right + * one position. To append a track to the end, set + * \a track_num to \c object->data.cue_sheet.num_tracks . + * \param track The track to insert. You may safely pass in a const + * pointer if \a copy is \c true. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks >= track_num \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); + +/** Insert a blank track in a CUESHEET block at the given index. + * + * A blank track is one in which all field values are zero. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index at which to insert the track. NOTE: this + * is not necessarily the same as the track's \a number + * field. The tracks at and after \a track_num move right + * one position. To append a track to the end, set + * \a track_num to \c object->data.cue_sheet.num_tracks . + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks >= track_num \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num); + +/** Delete a track in a CUESHEET block at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index into the track array of the track to + * delete. NOTE: this is not necessarily the same + * as the track's \a number field. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num); + +/** Check a cue sheet to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * cue sheet. + * + * \param object A pointer to an existing CUESHEET object. + * \param check_cd_da_subset If \c true, check CUESHEET against more + * stringent requirements for a CD-DA (audio) disc. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \retval FLAC__bool + * \c false if cue sheet is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation); + +/** Calculate and return the CDDB/freedb ID for a cue sheet. The function + * assumes the cue sheet corresponds to a CD; the result is undefined + * if the cuesheet's is_cd bit is not set. + * + * \param object A pointer to an existing CUESHEET object. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \retval FLAC__uint32 + * The unsigned integer representation of the CDDB/freedb ID + */ +FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object); + +/** Sets the MIME type of a PICTURE block. + * + * If \a copy is \c true, a copy of the string is stored; otherwise, the object + * takes ownership of the pointer. The existing string will be freed if this + * function is successful, otherwise the original string will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param mime_type A pointer to the MIME type string. The string must be + * ASCII characters 0x20-0x7e, NUL-terminated. No validation + * is done. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (mime_type != NULL) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy); + +/** Sets the description of a PICTURE block. + * + * If \a copy is \c true, a copy of the string is stored; otherwise, the object + * takes ownership of the pointer. The existing string will be freed if this + * function is successful, otherwise the original string will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a description if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param description A pointer to the description string. The string must be + * valid UTF-8, NUL-terminated. No validation is done. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (description != NULL) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy); + +/** Sets the picture data of a PICTURE block. + * + * If \a copy is \c true, a copy of the data is stored; otherwise, the object + * takes ownership of the pointer. Also sets the \a data_length field of the + * metadata object to what is passed in as the \a length parameter. The + * existing data will be freed if this function is successful, otherwise the + * original data and data_length will remain if \a copy is \c true and + * malloc() fails. + * + * \note It is safe to pass a const pointer to \a data if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param data A pointer to the data to set. + * \param length The length of \a data in bytes. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (data != NULL && length > 0) || + * (data == NULL && length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy); + +/** Check a PICTURE block to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * PICTURE block. + * + * \param object A pointer to existing PICTURE block to be checked. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \retval FLAC__bool + * \c false if PICTURE block is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/ordinals.h b/deps/flac-1.3.2/include/FLAC/ordinals.h new file mode 100644 index 0000000..ea52ea6 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/ordinals.h @@ -0,0 +1,86 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__ORDINALS_H +#define FLAC__ORDINALS_H + +#if defined(_MSC_VER) && _MSC_VER < 1600 + +/* Microsoft Visual Studio earlier than the 2010 version did not provide + * the 1999 ISO C Standard header file <stdint.h>. + */ + +typedef __int8 FLAC__int8; +typedef unsigned __int8 FLAC__uint8; + +typedef __int16 FLAC__int16; +typedef __int32 FLAC__int32; +typedef __int64 FLAC__int64; +typedef unsigned __int16 FLAC__uint16; +typedef unsigned __int32 FLAC__uint32; +typedef unsigned __int64 FLAC__uint64; + +#else + +/* For MSVC 2010 and everything else which provides <stdint.h>. */ + +#include <stdint.h> + +typedef int8_t FLAC__int8; +typedef uint8_t FLAC__uint8; + +typedef int16_t FLAC__int16; +typedef int32_t FLAC__int32; +typedef int64_t FLAC__int64; +typedef uint16_t FLAC__uint16; +typedef uint32_t FLAC__uint32; +typedef uint64_t FLAC__uint64; + +#endif + +typedef int FLAC__bool; + +typedef FLAC__uint8 FLAC__byte; + + +#ifdef true +#undef true +#endif +#ifdef false +#undef false +#endif +#ifndef __cplusplus +#define true 1 +#define false 0 +#endif + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/stream_decoder.h b/deps/flac-1.3.2/include/FLAC/stream_decoder.h new file mode 100644 index 0000000..39c958d --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/stream_decoder.h @@ -0,0 +1,1560 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__STREAM_DECODER_H +#define FLAC__STREAM_DECODER_H + +#include <stdio.h> /* for FILE */ +#include "export.h" +#include "format.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/stream_decoder.h + * + * \brief + * This module contains the functions which implement the stream + * decoder. + * + * See the detailed documentation in the + * \link flac_stream_decoder stream decoder \endlink module. + */ + +/** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces + * \ingroup flac + * + * \brief + * This module describes the decoder layers provided by libFLAC. + * + * The stream decoder can be used to decode complete streams either from + * the client via callbacks, or directly from a file, depending on how + * it is initialized. When decoding via callbacks, the client provides + * callbacks for reading FLAC data and writing decoded samples, and + * handling metadata and errors. If the client also supplies seek-related + * callback, the decoder function for sample-accurate seeking within the + * FLAC input is also available. When decoding from a file, the client + * needs only supply a filename or open \c FILE* and write/metadata/error + * callbacks; the rest of the callbacks are supplied internally. For more + * info see the \link flac_stream_decoder stream decoder \endlink module. + */ + +/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface + * \ingroup flac_decoder + * + * \brief + * This module contains the functions which implement the stream + * decoder. + * + * The stream decoder can decode native FLAC, and optionally Ogg FLAC + * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + * + * The basic usage of this decoder is as follows: + * - The program creates an instance of a decoder using + * FLAC__stream_decoder_new(). + * - The program overrides the default settings using + * FLAC__stream_decoder_set_*() functions. + * - The program initializes the instance to validate the settings and + * prepare for decoding using + * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() + * or FLAC__stream_decoder_init_file() for native FLAC, + * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() + * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC + * - The program calls the FLAC__stream_decoder_process_*() functions + * to decode data, which subsequently calls the callbacks. + * - The program finishes the decoding with FLAC__stream_decoder_finish(), + * which flushes the input and output and resets the decoder to the + * uninitialized state. + * - The instance may be used again or deleted with + * FLAC__stream_decoder_delete(). + * + * In more detail, the program will create a new instance by calling + * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() + * functions to override the default decoder options, and call + * one of the FLAC__stream_decoder_init_*() functions. + * + * There are three initialization functions for native FLAC, one for + * setting up the decoder to decode FLAC data from the client via + * callbacks, and two for decoding directly from a FLAC file. + * + * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). + * You must also supply several callbacks for handling I/O. Some (like + * seeking) are optional, depending on the capabilities of the input. + * + * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() + * or FLAC__stream_decoder_init_file(). Then you must only supply an open + * \c FILE* or filename and fewer callbacks; the decoder will handle + * the other callbacks internally. + * + * There are three similarly-named init functions for decoding from Ogg + * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + * library has been built with Ogg support. + * + * Once the decoder is initialized, your program will call one of several + * functions to start the decoding process: + * + * - FLAC__stream_decoder_process_single() - Tells the decoder to process at + * most one metadata block or audio frame and return, calling either the + * metadata callback or write callback, respectively, once. If the decoder + * loses sync it will return with only the error callback being called. + * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder + * to process the stream from the current location and stop upon reaching + * the first audio frame. The client will get one metadata, write, or error + * callback per metadata block, audio frame, or sync error, respectively. + * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder + * to process the stream from the current location until the read callback + * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or + * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, + * write, or error callback per metadata block, audio frame, or sync error, + * respectively. + * + * When the decoder has finished decoding (normally or through an abort), + * the instance is finished by calling FLAC__stream_decoder_finish(), which + * ensures the decoder is in the correct state and frees memory. Then the + * instance may be deleted with FLAC__stream_decoder_delete() or initialized + * again to decode another stream. + * + * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. + * At any point after the stream decoder has been initialized, the client can + * call this function to seek to an exact sample within the stream. + * Subsequently, the first time the write callback is called it will be + * passed a (possibly partial) block starting at that sample. + * + * If the client cannot seek via the callback interface provided, but still + * has another way of seeking, it can flush the decoder using + * FLAC__stream_decoder_flush() and start feeding data from the new position + * through the read callback. + * + * The stream decoder also provides MD5 signature checking. If this is + * turned on before initialization, FLAC__stream_decoder_finish() will + * report when the decoded MD5 signature does not match the one stored + * in the STREAMINFO block. MD5 checking is automatically turned off + * (until the next FLAC__stream_decoder_reset()) if there is no signature + * in the STREAMINFO block or when a seek is attempted. + * + * The FLAC__stream_decoder_set_metadata_*() functions deserve special + * attention. By default, the decoder only calls the metadata_callback for + * the STREAMINFO block. These functions allow you to tell the decoder + * explicitly which blocks to parse and return via the metadata_callback + * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), + * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), + * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify + * which blocks to return. Remember that metadata blocks can potentially + * be big (for example, cover art) so filtering out the ones you don't + * use can reduce the memory requirements of the decoder. Also note the + * special forms FLAC__stream_decoder_set_metadata_respond_application(id) + * and FLAC__stream_decoder_set_metadata_ignore_application(id) for + * filtering APPLICATION blocks based on the application ID. + * + * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but + * they still can legally be filtered from the metadata_callback. + * + * \note + * The "set" functions may only be called when the decoder is in the + * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after + * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but + * before FLAC__stream_decoder_init_*(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__stream_decoder_finish() resets all settings to the constructor + * defaults, including the callbacks. + * + * \{ + */ + + +/** State values for a FLAC__StreamDecoder + * + * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). + */ +typedef enum { + + FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, + /**< The decoder is ready to search for metadata. */ + + FLAC__STREAM_DECODER_READ_METADATA, + /**< The decoder is ready to or is in the process of reading metadata. */ + + FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, + /**< The decoder is ready to or is in the process of searching for the + * frame sync code. + */ + + FLAC__STREAM_DECODER_READ_FRAME, + /**< The decoder is ready to or is in the process of reading a frame. */ + + FLAC__STREAM_DECODER_END_OF_STREAM, + /**< The decoder has reached the end of the stream. */ + + FLAC__STREAM_DECODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ + + FLAC__STREAM_DECODER_SEEK_ERROR, + /**< An error occurred while seeking. The decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + */ + + FLAC__STREAM_DECODER_ABORTED, + /**< The decoder was aborted by the read or write callback. */ + + FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. The decoder is in an invalid + * state and can no longer be used. + */ + + FLAC__STREAM_DECODER_UNINITIALIZED + /**< The decoder is in the uninitialized state; one of the + * FLAC__stream_decoder_init_*() functions must be called before samples + * can be processed. + */ + +} FLAC__StreamDecoderState; + +/** Maps a FLAC__StreamDecoderState to a C string. + * + * Using a FLAC__StreamDecoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; + + +/** Possible return values for the FLAC__stream_decoder_init_*() functions. + */ +typedef enum { + + FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ + + FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ + + FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ + + FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. */ + + FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, + /**< fopen() failed in FLAC__stream_decoder_init_file() or + * FLAC__stream_decoder_init_ogg_file(). */ + + FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_decoder_init_*() was called when the decoder was + * already initialized, usually because + * FLAC__stream_decoder_finish() was not called. + */ + +} FLAC__StreamDecoderInitStatus; + +/** Maps a FLAC__StreamDecoderInitStatus to a C string. + * + * Using a FLAC__StreamDecoderInitStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; + + +/** Return values for the FLAC__StreamDecoder read callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted while at the end of the stream. Note that + * the client must only return this value when the read callback was + * called when already at the end of the stream. Otherwise, if the read + * itself moves to the end of the stream, the client should still return + * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on + * the next read callback it should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count + * of \c 0. + */ + + FLAC__STREAM_DECODER_READ_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + +} FLAC__StreamDecoderReadStatus; + +/** Maps a FLAC__StreamDecoderReadStatus to a C string. + * + * Using a FLAC__StreamDecoderReadStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; + + +/** Return values for the FLAC__StreamDecoder seek callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_SEEK_STATUS_OK, + /**< The seek was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamDecoderSeekStatus; + +/** Maps a FLAC__StreamDecoderSeekStatus to a C string. + * + * Using a FLAC__StreamDecoderSeekStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; + + +/** Return values for the FLAC__StreamDecoder tell callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_TELL_STATUS_OK, + /**< The tell was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support telling the position. */ + +} FLAC__StreamDecoderTellStatus; + +/** Maps a FLAC__StreamDecoderTellStatus to a C string. + * + * Using a FLAC__StreamDecoderTellStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; + + +/** Return values for the FLAC__StreamDecoder length callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_LENGTH_STATUS_OK, + /**< The length call was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + /**< Client does not support reporting the length. */ + +} FLAC__StreamDecoderLengthStatus; + +/** Maps a FLAC__StreamDecoderLengthStatus to a C string. + * + * Using a FLAC__StreamDecoderLengthStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; + + +/** Return values for the FLAC__StreamDecoder write callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, + /**< The write was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_WRITE_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + +} FLAC__StreamDecoderWriteStatus; + +/** Maps a FLAC__StreamDecoderWriteStatus to a C string. + * + * Using a FLAC__StreamDecoderWriteStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; + + +/** Possible values passed back to the FLAC__StreamDecoder error callback. + * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- + * all. The rest could be caused by bad sync (false synchronization on + * data that is not the start of a frame) or corrupted data. The error + * itself is the decoder's best guess at what happened assuming a correct + * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER + * could be caused by a correct sync on the start of a frame, but some + * data in the frame header was corrupted. Or it could be the result of + * syncing on a point the stream that looked like the starting of a frame + * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + * could be because the decoder encountered a valid frame made by a future + * version of the encoder which it cannot parse, or because of a false + * sync making it appear as though an encountered frame was generated by + * a future encoder. + */ +typedef enum { + + FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, + /**< An error in the stream caused the decoder to lose synchronization. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, + /**< The decoder encountered a corrupted frame header. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, + /**< The frame's data did not match the CRC in the footer. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + /**< The decoder encountered reserved fields in use in the stream. */ + +} FLAC__StreamDecoderErrorStatus; + +/** Maps a FLAC__StreamDecoderErrorStatus to a C string. + * + * Using a FLAC__StreamDecoderErrorStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; + + +/*********************************************************************** + * + * class FLAC__StreamDecoder + * + ***********************************************************************/ + +struct FLAC__StreamDecoderProtected; +struct FLAC__StreamDecoderPrivate; +/** The opaque structure definition for the stream decoder type. + * See the \link flac_stream_decoder stream decoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__StreamDecoder; + +/** Signature for the read callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs more input data. The address of the + * buffer to be filled is supplied, along with the number of bytes the + * buffer can hold. The callback may choose to supply less data and + * modify the byte count but must be careful not to overflow the buffer. + * The callback then returns a status code chosen from + * FLAC__StreamDecoderReadStatus. + * + * Here is an example of a read callback for stdio streams: + * \code + * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(*bytes > 0) { + * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); + * if(ferror(file)) + * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + * else if(*bytes == 0) + * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + * else + * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + * } + * else + * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param buffer A pointer to a location for the callee to store + * data to be decoded. + * \param bytes A pointer to the size of the buffer. On entry + * to the callback, it contains the maximum number + * of bytes that may be stored in \a buffer. The + * callee must set it to the actual number of bytes + * stored (0 in case of error or end-of-stream) before + * returning. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderReadStatus + * The callee's return status. Note that the callback should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if + * zero bytes were read and there is no more data to be read. + */ +typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +/** Signature for the seek callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs to seek the input stream. The decoder + * will pass the absolute byte offset to seek to, 0 meaning the + * beginning of the stream. + * + * Here is an example of a seek callback for stdio streams: + * \code + * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(file == stdin) + * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; + * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + * else + * return FLAC__STREAM_DECODER_SEEK_STATUS_OK; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param absolute_byte_offset The offset from the beginning of the stream + * to seek to. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderSeekStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); + +/** Signature for the tell callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder wants to know the current position of the + * stream. The callback should return the byte offset from the + * beginning of the stream. + * + * Here is an example of a tell callback for stdio streams: + * \code + * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * off_t pos; + * if(file == stdin) + * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; + * else if((pos = ftello(file)) < 0) + * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + * else { + * *absolute_byte_offset = (FLAC__uint64)pos; + * return FLAC__STREAM_DECODER_TELL_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param absolute_byte_offset A pointer to storage for the current offset + * from the beginning of the stream. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderTellStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + +/** Signature for the length callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder wants to know the total length of the stream + * in bytes. + * + * Here is an example of a length callback for stdio streams: + * \code + * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * struct stat filestats; + * + * if(file == stdin) + * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + * else if(fstat(fileno(file), &filestats) != 0) + * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; + * else { + * *stream_length = (FLAC__uint64)filestats.st_size; + * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param stream_length A pointer to storage for the length of the stream + * in bytes. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderLengthStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); + +/** Signature for the EOF callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs to know if the end of the stream has + * been reached. + * + * Here is an example of a EOF callback for stdio streams: + * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) + * \code + * { + * FILE *file = ((MyClientData*)client_data)->file; + * return feof(file)? true : false; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__bool + * \c true if the currently at the end of the stream, else \c false. + */ +typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); + +/** Signature for the write callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called when the decoder has decoded a + * single audio frame. The decoder will pass the frame metadata as well + * as an array of pointers (one for each channel) pointing to the + * decoded audio. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param frame The description of the decoded frame. See + * FLAC__Frame. + * \param buffer An array of pointers to decoded channels of data. + * Each pointer will point to an array of signed + * samples of length \a frame->header.blocksize. + * Channels will be ordered according to the FLAC + * specification; see the documentation for the + * <A HREF="../format.html#frame_header">frame header</A>. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderWriteStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); + +/** Signature for the metadata callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called when the decoder has decoded a + * metadata block. In a valid FLAC file there will always be one + * \c STREAMINFO block, followed by zero or more other metadata blocks. + * These will be supplied by the decoder in the same order as they + * appear in the stream and always before the first audio frame (i.e. + * write callback). The metadata block that is passed in must not be + * modified, and it doesn't live beyond the callback, so you should make + * a copy of it with FLAC__metadata_object_clone() if you will need it + * elsewhere. Since metadata blocks can potentially be large, by + * default the decoder only calls the metadata callback for the + * \c STREAMINFO block; you can instruct the decoder to pass or filter + * other blocks with FLAC__stream_decoder_set_metadata_*() calls. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param metadata The decoded metadata block. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + */ +typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/** Signature for the error callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called whenever an error occurs during + * decoding. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param status The error encountered by the decoder. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + */ +typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new stream decoder instance. The instance is created with + * default settings; see the individual FLAC__stream_decoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__StreamDecoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void); + +/** Free a decoder instance. Deletes the object pointed to by \a decoder. + * + * \param decoder A pointer to an existing decoder. + * \assert + * \code decoder != NULL \endcode + */ +FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); + + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** Set the serial number for the FLAC stream within the Ogg container. + * The default behavior is to use the serial number of the first Ogg + * page. Setting a serial number here will explicitly specify which + * stream is to be decoded. + * + * \note + * This does not need to be set for native FLAC decoding. + * + * \default \c use serial number of first page + * \param decoder A decoder instance to set. + * \param serial_number See above. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number); + +/** Set the "MD5 signature checking" flag. If \c true, the decoder will + * compute the MD5 signature of the unencoded audio data while decoding + * and compare it to the signature from the STREAMINFO block, if it + * exists, during FLAC__stream_decoder_finish(). + * + * MD5 signature checking will be turned off (until the next + * FLAC__stream_decoder_reset()) if there is no signature in the + * STREAMINFO block or when a seek is attempted. + * + * Clients that do not use the MD5 check should leave this off to speed + * up decoding. + * + * \default \c false + * \param decoder A decoder instance to set. + * \param value Flag value (see above). + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value); + +/** Direct the decoder to pass on all metadata blocks of type \a type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param type See above. + * \assert + * \code decoder != NULL \endcode + * \a type is valid + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); + +/** Direct the decoder to pass on all APPLICATION metadata blocks of the + * given \a id. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param id See above. + * \assert + * \code decoder != NULL \endcode + * \code id != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); + +/** Direct the decoder to pass on all metadata blocks of any type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); + +/** Direct the decoder to filter out all metadata blocks of type \a type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param type See above. + * \assert + * \code decoder != NULL \endcode + * \a type is valid + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); + +/** Direct the decoder to filter out all APPLICATION metadata blocks of + * the given \a id. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param id See above. + * \assert + * \code decoder != NULL \endcode + * \code id != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); + +/** Direct the decoder to filter out all metadata blocks of any type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); + +/** Get the current decoder state. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderState + * The current decoder state. + */ +FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); + +/** Get the current decoder state as a C string. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval const char * + * The decoder state as a C string. Do not modify the contents. + */ +FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); + +/** Get the "MD5 signature checking" flag. + * This is the value of the setting, not whether or not the decoder is + * currently checking the MD5 (remember, it can be turned off automatically + * by a seek). When the decoder is reset the flag will be restored to the + * value returned by this function. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * See above. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); + +/** Get the total number of samples in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the \c STREAMINFO block. A value of \c 0 means "unknown". + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); + +/** Get the current number of channels in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); + +/** Get the current channel assignment in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__ChannelAssignment + * See above. + */ +FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); + +/** Get the current sample resolution in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); + +/** Get the current sample rate in Hz of the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); + +/** Get the current blocksize of the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); + +/** Returns the decoder's current read position within the stream. + * The position is the byte offset from the start of the stream. + * Bytes before this position have been fully decoded. Note that + * there may still be undecoded bytes in the decoder's read FIFO. + * The returned position is correct even after a seek. + * + * \warning This function currently only works for native FLAC, + * not Ogg FLAC streams. + * + * \param decoder A decoder instance to query. + * \param position Address at which to return the desired position. + * \assert + * \code decoder != NULL \endcode + * \code position != NULL \endcode + * \retval FLAC__bool + * \c true if successful, \c false if the stream is not native FLAC, + * or there was an error from the 'tell' callback or it returned + * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); + +/** Initialize the decoder instance to decode native FLAC streams. + * + * This flavor of initialization sets up the decoder to decode from a + * native FLAC stream. I/O is performed via callbacks to the client. + * For decoding from a plain file via filename or open FILE*, + * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param read_callback See FLAC__StreamDecoderReadCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamDecoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is not \c NULL then a + * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param tell_callback See FLAC__StreamDecoderTellCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param length_callback See FLAC__StreamDecoderLengthCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a length_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param eof_callback See FLAC__StreamDecoderEofCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a eof_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c false + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC streams. + * + * This flavor of initialization sets up the decoder to decode from a + * FLAC stream in an Ogg container. I/O is performed via callbacks to the + * client. For decoding from a plain file via filename or open FILE*, + * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param read_callback See FLAC__StreamDecoderReadCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamDecoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is not \c NULL then a + * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param tell_callback See FLAC__StreamDecoderTellCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param length_callback See FLAC__StreamDecoderLengthCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a length_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param eof_callback See FLAC__StreamDecoderEofCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a eof_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c false + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode native FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a + * plain native FLAC file. For non-stdio streams, you must use + * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param file An open FLAC file. The file should have been + * opened with mode \c "rb" and rewound. The file + * becomes owned by the decoder and should not be + * manipulated by the client while decoding. + * Unless \a file is \c stdin, it will be closed + * when FLAC__stream_decoder_finish() is called. + * Note however that seeking will not work when + * decoding from \c stdout since it is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a + * plain Ogg FLAC file. For non-stdio streams, you must use + * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param file An open FLAC file. The file should have been + * opened with mode \c "rb" and rewound. The file + * becomes owned by the decoder and should not be + * manipulated by the client while decoding. + * Unless \a file is \c stdin, it will be closed + * when FLAC__stream_decoder_finish() is called. + * Note however that seeking will not work when + * decoding from \c stdout since it is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode native FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a plain + * native FLAC file. If POSIX fopen() semantics are not sufficient, (for + * example, with Unicode filenames on Windows), you must use + * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param filename The name of the file to decode from. The file will + * be opened with fopen(). Use \c NULL to decode from + * \c stdin. Note that \c stdin is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a plain + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for + * example, with Unicode filenames on Windows), you must use + * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param filename The name of the file to decode from. The file will + * be opened with fopen(). Use \c NULL to decode from + * \c stdin. Note that \c stdin is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Finish the decoding process. + * Flushes the decoding buffer, releases resources, resets the decoder + * settings to their defaults, and returns the decoder state to + * FLAC__STREAM_DECODER_UNINITIALIZED. + * + * In the event of a prematurely-terminated decode, it is not strictly + * necessary to call this immediately before FLAC__stream_decoder_delete() + * but it is good practice to match every FLAC__stream_decoder_init_*() + * with a FLAC__stream_decoder_finish(). + * + * \param decoder An uninitialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if MD5 checking is on AND a STREAMINFO block was available + * AND the MD5 signature in the STREAMINFO block was non-zero AND the + * signature does not match the one computed by the decoder; else + * \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder); + +/** Flush the stream input. + * The decoder's input buffer will be cleared and the state set to + * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn + * off MD5 checking. + * + * \param decoder A decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false if a memory allocation + * error occurs (in which case the state will be set to + * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder); + +/** Reset the decoding process. + * The decoder's input buffer will be cleared and the state set to + * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to + * FLAC__stream_decoder_finish() except that the settings are + * preserved; there is no need to call FLAC__stream_decoder_init_*() + * before decoding again. MD5 checking will be restored to its original + * setting. + * + * If the decoder is seekable, or was initialized with + * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(), + * the decoder will also attempt to seek to the beginning of the file. + * If this rewind fails, this function will return \c false. It follows + * that FLAC__stream_decoder_reset() cannot be used when decoding from + * \c stdin. + * + * If the decoder was initialized with FLAC__stream_encoder_init*_stream() + * and is not seekable (i.e. no seek callback was provided or the seek + * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it + * is the duty of the client to start feeding data from the beginning of + * the stream on the next FLAC__stream_decoder_process() or + * FLAC__stream_decoder_process_interleaved() call. + * + * \param decoder A decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false if a memory allocation occurs + * (in which case the state will be set to + * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error + * occurs (the state will be unchanged). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); + +/** Decode one metadata block or audio frame. + * This version instructs the decoder to decode a either a single metadata + * block or a single frame and stop, unless the callbacks return a fatal + * error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * As the decoder needs more input it will call the read callback. + * Depending on what was decoded, the metadata or write callback will be + * called with the decoded metadata block or audio frame. + * + * Unless there is a fatal read error or end of stream, this function + * will return once one whole frame is decoded. In other words, if the + * stream is not synchronized or points to a corrupt frame header, the + * decoder will continue to try and resync until it gets to a valid + * frame, then decode one frame, then return. If the decoder points to + * a frame whose frame CRC in the frame footer does not match the + * computed frame CRC, this function will issue a + * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the + * error callback, and return, having decoded one complete, although + * corrupt, frame. (Such corrupted frames are sent as silence of the + * correct length to the write callback.) + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); + +/** Decode until the end of the metadata. + * This version instructs the decoder to decode from the current position + * and continue until all the metadata has been read, or until the + * callbacks return a fatal error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * As the decoder needs more input it will call the read callback. + * As each metadata block is decoded, the metadata callback will be called + * with the decoded metadata. + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); + +/** Decode until the end of the stream. + * This version instructs the decoder to decode from the current position + * and continue until the end of stream (the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the + * callbacks return a fatal error. + * + * As the decoder needs more input it will call the read callback. + * As each metadata block and frame is decoded, the metadata or write + * callback will be called with the decoded metadata or frame. + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); + +/** Skip one audio frame. + * This version instructs the decoder to 'skip' a single frame and stop, + * unless the callbacks return a fatal error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * The decoding flow is the same as what occurs when + * FLAC__stream_decoder_process_single() is called to process an audio + * frame, except that this function does not decode the parsed data into + * PCM or call the write callback. The integrity of the frame is still + * checked the same way as in the other process functions. + * + * This function will return once one whole frame is skipped, in the + * same way that FLAC__stream_decoder_process_single() will return once + * one whole frame is decoded. + * + * This function can be used in more quickly determining FLAC frame + * boundaries when decoding of the actual data is not needed, for + * example when an application is separating a FLAC stream into frames + * for editing or storing in a container. To do this, the application + * can use FLAC__stream_decoder_skip_single_frame() to quickly advance + * to the next frame, then use + * FLAC__stream_decoder_get_decode_position() to find the new frame + * boundary. + * + * This function should only be called when the stream has advanced + * past all the metadata, otherwise it will return \c false. + * + * \param decoder An initialized decoder instance not in a metadata + * state. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), or if the decoder + * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or + * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); + +/** Flush the input and seek to an absolute sample. + * Decoding will resume at the given sample. Note that because of + * this, the next write callback may contain a partial block. The + * client must support seeking the input or this function will fail + * and return \c false. Furthermore, if the decoder state is + * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + * + * \param decoder A decoder instance. + * \param sample The target sample number to seek to. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/FLAC/stream_encoder.h b/deps/flac-1.3.2/include/FLAC/stream_encoder.h new file mode 100644 index 0000000..40a2fd3 --- /dev/null +++ b/deps/flac-1.3.2/include/FLAC/stream_encoder.h @@ -0,0 +1,1790 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__STREAM_ENCODER_H +#define FLAC__STREAM_ENCODER_H + +#include <stdio.h> /* for FILE */ +#include "export.h" +#include "format.h" +#include "stream_decoder.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/stream_encoder.h + * + * \brief + * This module contains the functions which implement the stream + * encoder. + * + * See the detailed documentation in the + * \link flac_stream_encoder stream encoder \endlink module. + */ + +/** \defgroup flac_encoder FLAC/ \*_encoder.h: encoder interfaces + * \ingroup flac + * + * \brief + * This module describes the encoder layers provided by libFLAC. + * + * The stream encoder can be used to encode complete streams either to the + * client via callbacks, or directly to a file, depending on how it is + * initialized. When encoding via callbacks, the client provides a write + * callback which will be called whenever FLAC data is ready to be written. + * If the client also supplies a seek callback, the encoder will also + * automatically handle the writing back of metadata discovered while + * encoding, like stream info, seek points offsets, etc. When encoding to + * a file, the client needs only supply a filename or open \c FILE* and an + * optional progress callback for periodic notification of progress; the + * write and seek callbacks are supplied internally. For more info see the + * \link flac_stream_encoder stream encoder \endlink module. + */ + +/** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface + * \ingroup flac_encoder + * + * \brief + * This module contains the functions which implement the stream + * encoder. + * + * The stream encoder can encode to native FLAC, and optionally Ogg FLAC + * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + * + * The basic usage of this encoder is as follows: + * - The program creates an instance of an encoder using + * FLAC__stream_encoder_new(). + * - The program overrides the default settings using + * FLAC__stream_encoder_set_*() functions. At a minimum, the following + * functions should be called: + * - FLAC__stream_encoder_set_channels() + * - FLAC__stream_encoder_set_bits_per_sample() + * - FLAC__stream_encoder_set_sample_rate() + * - FLAC__stream_encoder_set_ogg_serial_number() (if encoding to Ogg FLAC) + * - FLAC__stream_encoder_set_total_samples_estimate() (if known) + * - If the application wants to control the compression level or set its own + * metadata, then the following should also be called: + * - FLAC__stream_encoder_set_compression_level() + * - FLAC__stream_encoder_set_verify() + * - FLAC__stream_encoder_set_metadata() + * - The rest of the set functions should only be called if the client needs + * exact control over how the audio is compressed; thorough understanding + * of the FLAC format is necessary to achieve good results. + * - The program initializes the instance to validate the settings and + * prepare for encoding using + * - FLAC__stream_encoder_init_stream() or FLAC__stream_encoder_init_FILE() + * or FLAC__stream_encoder_init_file() for native FLAC + * - FLAC__stream_encoder_init_ogg_stream() or FLAC__stream_encoder_init_ogg_FILE() + * or FLAC__stream_encoder_init_ogg_file() for Ogg FLAC + * - The program calls FLAC__stream_encoder_process() or + * FLAC__stream_encoder_process_interleaved() to encode data, which + * subsequently calls the callbacks when there is encoder data ready + * to be written. + * - The program finishes the encoding with FLAC__stream_encoder_finish(), + * which causes the encoder to encode any data still in its input pipe, + * update the metadata with the final encoding statistics if output + * seeking is possible, and finally reset the encoder to the + * uninitialized state. + * - The instance may be used again or deleted with + * FLAC__stream_encoder_delete(). + * + * In more detail, the stream encoder functions similarly to the + * \link flac_stream_decoder stream decoder \endlink, but has fewer + * callbacks and more options. Typically the client will create a new + * instance by calling FLAC__stream_encoder_new(), then set the necessary + * parameters with FLAC__stream_encoder_set_*(), and initialize it by + * calling one of the FLAC__stream_encoder_init_*() functions. + * + * Unlike the decoders, the stream encoder has many options that can + * affect the speed and compression ratio. When setting these parameters + * you should have some basic knowledge of the format (see the + * <A HREF="../documentation_format_overview.html">user-level documentation</A> + * or the <A HREF="../format.html">formal description</A>). The + * FLAC__stream_encoder_set_*() functions themselves do not validate the + * values as many are interdependent. The FLAC__stream_encoder_init_*() + * functions will do this, so make sure to pay attention to the state + * returned by FLAC__stream_encoder_init_*() to make sure that it is + * FLAC__STREAM_ENCODER_INIT_STATUS_OK. Any parameters that are not set + * before FLAC__stream_encoder_init_*() will take on the defaults from + * the constructor. + * + * There are three initialization functions for native FLAC, one for + * setting up the encoder to encode FLAC data to the client via + * callbacks, and two for encoding directly to a file. + * + * For encoding via callbacks, use FLAC__stream_encoder_init_stream(). + * You must also supply a write callback which will be called anytime + * there is raw encoded data to write. If the client can seek the output + * it is best to also supply seek and tell callbacks, as this allows the + * encoder to go back after encoding is finished to write back + * information that was collected while encoding, like seek point offsets, + * frame sizes, etc. + * + * For encoding directly to a file, use FLAC__stream_encoder_init_FILE() + * or FLAC__stream_encoder_init_file(). Then you must only supply a + * filename or open \c FILE*; the encoder will handle all the callbacks + * internally. You may also supply a progress callback for periodic + * notification of the encoding progress. + * + * There are three similarly-named init functions for encoding to Ogg + * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + * library has been built with Ogg support. + * + * The call to FLAC__stream_encoder_init_*() currently will also immediately + * call the write callback several times, once with the \c fLaC signature, + * and once for each encoded metadata block. Note that for Ogg FLAC + * encoding you will usually get at least twice the number of callbacks than + * with native FLAC, one for the Ogg page header and one for the page body. + * + * After initializing the instance, the client may feed audio data to the + * encoder in one of two ways: + * + * - Channel separate, through FLAC__stream_encoder_process() - The client + * will pass an array of pointers to buffers, one for each channel, to + * the encoder, each of the same length. The samples need not be + * block-aligned, but each channel should have the same number of samples. + * - Channel interleaved, through + * FLAC__stream_encoder_process_interleaved() - The client will pass a single + * pointer to data that is channel-interleaved (i.e. channel0_sample0, + * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). + * Again, the samples need not be block-aligned but they must be + * sample-aligned, i.e. the first value should be channel0_sample0 and + * the last value channelN_sampleM. + * + * Note that for either process call, each sample in the buffers should be a + * signed integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the resolution + * is 16 bits per sample, the samples should all be in the range [-32768,32767]. + * + * When the client is finished encoding data, it calls + * FLAC__stream_encoder_finish(), which causes the encoder to encode any + * data still in its input pipe, and call the metadata callback with the + * final encoding statistics. Then the instance may be deleted with + * FLAC__stream_encoder_delete() or initialized again to encode another + * stream. + * + * For programs that write their own metadata, but that do not know the + * actual metadata until after encoding, it is advantageous to instruct + * the encoder to write a PADDING block of the correct size, so that + * instead of rewriting the whole stream after encoding, the program can + * just overwrite the PADDING block. If only the maximum size of the + * metadata is known, the program can write a slightly larger padding + * block, then split it after encoding. + * + * Make sure you understand how lengths are calculated. All FLAC metadata + * blocks have a 4 byte header which contains the type and length. This + * length does not include the 4 bytes of the header. See the format page + * for the specification of metadata blocks and their lengths. + * + * \note + * If you are writing the FLAC data to a file via callbacks, make sure it + * is open for update (e.g. mode "w+" for stdio streams). This is because + * after the first encoding pass, the encoder will try to seek back to the + * beginning of the stream, to the STREAMINFO block, to write some data + * there. (If using FLAC__stream_encoder_init*_file() or + * FLAC__stream_encoder_init*_FILE(), the file is managed internally.) + * + * \note + * The "set" functions may only be called when the encoder is in the + * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after + * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but + * before FLAC__stream_encoder_init_*(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__stream_encoder_finish() resets all settings to the constructor + * defaults. + * + * \{ + */ + + +/** State values for a FLAC__StreamEncoder. + * + * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state(). + * + * If the encoder gets into any other state besides \c FLAC__STREAM_ENCODER_OK + * or \c FLAC__STREAM_ENCODER_UNINITIALIZED, it becomes invalid for encoding and + * must be deleted with FLAC__stream_encoder_delete(). + */ +typedef enum { + + FLAC__STREAM_ENCODER_OK = 0, + /**< The encoder is in the normal OK state and samples can be processed. */ + + FLAC__STREAM_ENCODER_UNINITIALIZED, + /**< The encoder is in the uninitialized state; one of the + * FLAC__stream_encoder_init_*() functions must be called before samples + * can be processed. + */ + + FLAC__STREAM_ENCODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ + + FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR, + /**< An error occurred in the underlying verify stream decoder; + * check FLAC__stream_encoder_get_verify_decoder_state(). + */ + + FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA, + /**< The verify decoder detected a mismatch between the original + * audio signal and the decoded audio signal. + */ + + FLAC__STREAM_ENCODER_CLIENT_ERROR, + /**< One of the callbacks returned a fatal error. */ + + FLAC__STREAM_ENCODER_IO_ERROR, + /**< An I/O error occurred while opening/reading/writing a file. + * Check \c errno. + */ + + FLAC__STREAM_ENCODER_FRAMING_ERROR, + /**< An error occurred while writing the stream; usually, the + * write_callback returned an error. + */ + + FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR + /**< Memory allocation failed. */ + +} FLAC__StreamEncoderState; + +/** Maps a FLAC__StreamEncoderState to a C string. + * + * Using a FLAC__StreamEncoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderStateString[]; + + +/** Possible return values for the FLAC__stream_encoder_init_*() functions. + */ +typedef enum { + + FLAC__STREAM_ENCODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR, + /**< General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS, + /**< The encoder has an invalid setting for number of channels. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE, + /**< The encoder has an invalid setting for bits-per-sample. + * FLAC supports 4-32 bps but the reference encoder currently supports + * only up to 24 bps. + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE, + /**< The encoder has an invalid setting for the input sample rate. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE, + /**< The encoder has an invalid setting for the block size. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER, + /**< The encoder has an invalid setting for the maximum LPC order. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION, + /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER, + /**< The specified block size is less than the maximum LPC order. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE, + /**< The encoder is bound to the <A HREF="../format.html#subset">Subset</A> but other settings violate it. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA, + /**< The metadata input to the encoder is invalid, in one of the following ways: + * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0 + * - One of the metadata blocks contains an undefined type + * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal() + * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal() + * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_encoder_init_*() was called when the encoder was + * already initialized, usually because + * FLAC__stream_encoder_finish() was not called. + */ + +} FLAC__StreamEncoderInitStatus; + +/** Maps a FLAC__StreamEncoderInitStatus to a C string. + * + * Using a FLAC__StreamEncoderInitStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderInitStatusString[]; + + +/** Return values for the FLAC__StreamEncoder read callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ + + FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted at the end of the stream. */ + + FLAC__STREAM_ENCODER_READ_STATUS_ABORT, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED + /**< Client does not support reading back from the output. */ + +} FLAC__StreamEncoderReadStatus; + +/** Maps a FLAC__StreamEncoderReadStatus to a C string. + * + * Using a FLAC__StreamEncoderReadStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderReadStatusString[]; + + +/** Return values for the FLAC__StreamEncoder write callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0, + /**< The write was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR + /**< An unrecoverable error occurred. The encoder will return from the process call. */ + +} FLAC__StreamEncoderWriteStatus; + +/** Maps a FLAC__StreamEncoderWriteStatus to a C string. + * + * Using a FLAC__StreamEncoderWriteStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[]; + + +/** Return values for the FLAC__StreamEncoder seek callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_SEEK_STATUS_OK, + /**< The seek was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamEncoderSeekStatus; + +/** Maps a FLAC__StreamEncoderSeekStatus to a C string. + * + * Using a FLAC__StreamEncoderSeekStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[]; + + +/** Return values for the FLAC__StreamEncoder tell callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_TELL_STATUS_OK, + /**< The tell was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamEncoderTellStatus; + +/** Maps a FLAC__StreamEncoderTellStatus to a C string. + * + * Using a FLAC__StreamEncoderTellStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderTellStatusString[]; + + +/*********************************************************************** + * + * class FLAC__StreamEncoder + * + ***********************************************************************/ + +struct FLAC__StreamEncoderProtected; +struct FLAC__StreamEncoderPrivate; +/** The opaque structure definition for the stream encoder type. + * See the \link flac_stream_encoder stream encoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__StreamEncoder; + +/** Signature for the read callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_encoder_init_ogg_stream() if seeking is supported. + * The supplied function will be called when the encoder needs to read back + * encoded data. This happens during the metadata callback, when the encoder + * has to read, modify, and rewrite the metadata (e.g. seekpoints) gathered + * while encoding. The address of the buffer to be filled is supplied, along + * with the number of bytes the buffer can hold. The callback may choose to + * supply less data and modify the byte count but must be careful not to + * overflow the buffer. The callback then returns a status code chosen from + * FLAC__StreamEncoderReadStatus. + * + * Here is an example of a read callback for stdio streams: + * \code + * FLAC__StreamEncoderReadStatus read_cb(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(*bytes > 0) { + * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); + * if(ferror(file)) + * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + * else if(*bytes == 0) + * return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM; + * else + * return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; + * } + * else + * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param buffer A pointer to a location for the callee to store + * data to be encoded. + * \param bytes A pointer to the size of the buffer. On entry + * to the callback, it contains the maximum number + * of bytes that may be stored in \a buffer. The + * callee must set it to the actual number of bytes + * stored (0 in case of error or end-of-stream) before + * returning. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_set_client_data(). + * \retval FLAC__StreamEncoderReadStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +/** Signature for the write callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * by the encoder anytime there is raw encoded data ready to write. It may + * include metadata mixed with encoded audio frames and the data is not + * guaranteed to be aligned on frame or metadata block boundaries. + * + * The only duty of the callback is to write out the \a bytes worth of data + * in \a buffer to the current position in the output stream. The arguments + * \a samples and \a current_frame are purely informational. If \a samples + * is greater than \c 0, then \a current_frame will hold the current frame + * number that is being written; otherwise it indicates that the write + * callback is being called to write metadata. + * + * \note + * Unlike when writing to native FLAC, when writing to Ogg FLAC the + * write callback will be called twice when writing each audio + * frame; once for the page header, and once for the page body. + * When writing the page header, the \a samples argument to the + * write callback will be \c 0. + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param buffer An array of encoded data of length \a bytes. + * \param bytes The byte length of \a buffer. + * \param samples The number of samples encoded by \a buffer. + * \c 0 has a special meaning; see above. + * \param current_frame The number of the current frame being encoded. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderWriteStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); + +/** Signature for the seek callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * when the encoder needs to seek the output stream. The encoder will pass + * the absolute byte offset to seek to, 0 meaning the beginning of the stream. + * + * Here is an example of a seek callback for stdio streams: + * \code + * FLAC__StreamEncoderSeekStatus seek_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(file == stdin) + * return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED; + * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + * return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; + * else + * return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param absolute_byte_offset The offset from the beginning of the stream + * to seek to. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderSeekStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderSeekStatus (*FLAC__StreamEncoderSeekCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); + +/** Signature for the tell callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * when the encoder needs to know the current position of the output stream. + * + * \warning + * The callback must return the true current byte offset of the output to + * which the encoder is writing. If you are buffering the output, make + * sure and take this into account. If you are writing directly to a + * FILE* from your write callback, ftell() is sufficient. If you are + * writing directly to a file descriptor from your write callback, you + * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to + * these points to rewrite metadata after encoding. + * + * Here is an example of a tell callback for stdio streams: + * \code + * FLAC__StreamEncoderTellStatus tell_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * off_t pos; + * if(file == stdin) + * return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED; + * else if((pos = ftello(file)) < 0) + * return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR; + * else { + * *absolute_byte_offset = (FLAC__uint64)pos; + * return FLAC__STREAM_ENCODER_TELL_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param absolute_byte_offset The address at which to store the current + * position of the output. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderTellStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderTellStatus (*FLAC__StreamEncoderTellCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + +/** Signature for the metadata callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * once at the end of encoding with the populated STREAMINFO structure. This + * is so the client can seek back to the beginning of the file and write the + * STREAMINFO block with the correct statistics after encoding (like + * minimum/maximum frame size and total samples). + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param metadata The final populated STREAMINFO block. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + */ +typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/** Signature for the progress callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE(). + * The supplied function will be called when the encoder has finished + * writing a frame. The \c total_frames_estimate argument to the + * callback will be based on the value from + * FLAC__stream_encoder_set_total_samples_estimate(). + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param bytes_written Bytes written so far. + * \param samples_written Samples written so far. + * \param frames_written Frames written so far. + * \param total_frames_estimate The estimate of the total number of + * frames to be written. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + */ +typedef void (*FLAC__StreamEncoderProgressCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new stream encoder instance. The instance is created with + * default settings; see the individual FLAC__stream_encoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__StreamEncoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void); + +/** Free an encoder instance. Deletes the object pointed to by \a encoder. + * + * \param encoder A pointer to an existing encoder. + * \assert + * \code encoder != NULL \endcode + */ +FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder); + + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** Set the serial number for the FLAC stream to use in the Ogg container. + * + * \note + * This does not need to be set for native FLAC encoding. + * + * \note + * It is recommended to set a serial number explicitly as the default of '0' + * may collide with other streams. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param serial_number See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long serial_number); + +/** Set the "verify" flag. If \c true, the encoder will verify it's own + * encoded output by feeding it through an internal decoder and comparing + * the original signal against the decoded signal. If a mismatch occurs, + * the process call will return \c false. Note that this will slow the + * encoding process by the extra time required for decoding and comparison. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the <A HREF="../format.html#subset">Subset</A> flag. If \c true, + * the encoder will comply with the Subset and will check the + * settings during FLAC__stream_encoder_init_*() to see if all settings + * comply. If \c false, the settings may take advantage of the full + * range that the format allows. + * + * Make sure you know what it entails before setting this to \c false. + * + * \default \c true + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the number of channels to be encoded. + * + * \default \c 2 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the sample resolution of the input to be encoded. + * + * \warning + * Do not feed the encoder data that is wider than the value you + * set here or you will generate an invalid stream. + * + * \default \c 16 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the sample rate (in Hz) of the input to be encoded. + * + * \default \c 44100 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the compression level + * + * The compression level is roughly proportional to the amount of effort + * the encoder expends to compress the file. A higher level usually + * means more computation but higher compression. The default level is + * suitable for most applications. + * + * Currently the levels range from \c 0 (fastest, least compression) to + * \c 8 (slowest, most compression). A value larger than \c 8 will be + * treated as \c 8. + * + * This function automatically calls the following other \c _set_ + * functions with appropriate values, so the client does not need to + * unless it specifically wants to override them: + * - FLAC__stream_encoder_set_do_mid_side_stereo() + * - FLAC__stream_encoder_set_loose_mid_side_stereo() + * - FLAC__stream_encoder_set_apodization() + * - FLAC__stream_encoder_set_max_lpc_order() + * - FLAC__stream_encoder_set_qlp_coeff_precision() + * - FLAC__stream_encoder_set_do_qlp_coeff_prec_search() + * - FLAC__stream_encoder_set_do_escape_coding() + * - FLAC__stream_encoder_set_do_exhaustive_model_search() + * - FLAC__stream_encoder_set_min_residual_partition_order() + * - FLAC__stream_encoder_set_max_residual_partition_order() + * - FLAC__stream_encoder_set_rice_parameter_search_dist() + * + * The actual values set for each level are: + * <table> + * <tr> + * <td><b>level</b></td> + * <td>do mid-side stereo</td> + * <td>loose mid-side stereo</td> + * <td>apodization</td> + * <td>max lpc order</td> + * <td>qlp coeff precision</td> + * <td>qlp coeff prec search</td> + * <td>escape coding</td> + * <td>exhaustive model search</td> + * <td>min residual partition order</td> + * <td>max residual partition order</td> + * <td>rice parameter search dist</td> + * </tr> + * <tr> <td><b>0</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr> + * <tr> <td><b>1</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr> + * <tr> <td><b>2</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr> + * <tr> <td><b>3</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>6</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr> + * <tr> <td><b>4</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr> + * <tr> <td><b>5</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>5</td> <td>0</td> </tr> + * <tr> <td><b>6</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr> + * <tr> <td><b>7</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr> + * <tr> <td><b>8</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2);punchout_tukey(3)</td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr> + * </table> + * + * \default \c 5 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the blocksize to use while encoding. + * + * The number of samples to use per frame. Use \c 0 to let the encoder + * estimate a blocksize; this is usually best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set to \c true to enable mid-side encoding on stereo input. The + * number of channels must be 2 for this to have any effect. Set to + * \c false to use only independent channel coding. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set to \c true to enable adaptive switching between mid-side and + * left-right encoding on stereo input. Set to \c false to use + * exhaustive searching. Setting this to \c true requires + * FLAC__stream_encoder_set_do_mid_side_stereo() to also be set to + * \c true in order to have any effect. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Sets the apodization function(s) the encoder will use when windowing + * audio data for LPC analysis. + * + * The \a specification is a plain ASCII string which specifies exactly + * which functions to use. There may be more than one (up to 32), + * separated by \c ';' characters. Some functions take one or more + * comma-separated arguments in parentheses. + * + * The available functions are \c bartlett, \c bartlett_hann, + * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, + * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, + * \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]), + * \c punchout_tukey(n[/ov[/P]]), \c welch. + * + * For \c gauss(STDDEV), STDDEV specifies the standard deviation + * (0<STDDEV<=0.5). + * + * For \c tukey(P), P specifies the fraction of the window that is + * tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1 + * corresponds to \c hann. + * + * Specifying \c partial_tukey or \c punchout_tukey works a little + * different. These do not specify a single apodization function, but + * a series of them with some overlap. partial_tukey specifies a series + * of small windows (all treated separately) while punchout_tukey + * specifies a series of windows that have a hole in them. In this way, + * the predictor is constructed with only a part of the block, which + * helps in case a block consists of dissimilar parts. + * + * The three parameters that can be specified for the functions are + * n, ov and P. n is the number of functions to add, ov is the overlap + * of the windows in case of partial_tukey and the overlap in the gaps + * in case of punchout_tukey. P is the fraction of the window that is + * tapered, like with a regular tukey window. The function can be + * specified with only a number, a number and an overlap, or a number + * an overlap and a P, for example, partial_tukey(3), partial_tukey(3/0.3) + * and partial_tukey(3/0.3/0.5) are all valid. ov should be smaller than 1 + * and can be negative. + * + * Example specifications are \c "blackman" or + * \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)" + * + * Any function that is specified erroneously is silently dropped. Up + * to 32 functions are kept, the rest are dropped. If the specification + * is empty the encoder defaults to \c "tukey(0.5)". + * + * When more than one function is specified, then for every subframe the + * encoder will try each of them separately and choose the window that + * results in the smallest compressed subframe. + * + * Note that each function specified causes the encoder to occupy a + * floating point array in which to store the window. Also note that the + * values of P, STDDEV and ov are locale-specific, so if the comma + * separator specified by the locale is a comma, a comma should be used. + * + * \default \c "tukey(0.5)" + * \param encoder An encoder instance to set. + * \param specification See above. + * \assert + * \code encoder != NULL \endcode + * \code specification != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification); + +/** Set the maximum LPC order, or \c 0 to use only the fixed predictors. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the precision, in bits, of the quantized linear predictor + * coefficients, or \c 0 to let the encoder select it based on the + * blocksize. + * + * \note + * In the current implementation, qlp_coeff_precision + bits_per_sample must + * be less than 32. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set to \c false to use only the specified quantized linear predictor + * coefficient precision, or \c true to search neighboring precision + * values and use the best one. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Deprecated. Setting this value has no effect. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set to \c false to let the encoder estimate the best model order + * based on the residual signal energy, or \c true to force the + * encoder to evaluate all order models and select the best. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the minimum partition order to search when coding the residual. + * This is used in tandem with + * FLAC__stream_encoder_set_max_residual_partition_order(). + * + * The partition order determines the context size in the residual. + * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>. + * + * Set both min and max values to \c 0 to force a single context, + * whose Rice parameter is based on the residual signal variance. + * Otherwise, set a min and max order, and the encoder will search + * all orders, using the mean of each context for its Rice parameter, + * and use the best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the maximum partition order to search when coding the residual. + * This is used in tandem with + * FLAC__stream_encoder_set_min_residual_partition_order(). + * + * The partition order determines the context size in the residual. + * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>. + * + * Set both min and max values to \c 0 to force a single context, + * whose Rice parameter is based on the residual signal variance. + * Otherwise, set a min and max order, and the encoder will search + * all orders, using the mean of each context for its Rice parameter, + * and use the best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Deprecated. Setting this value has no effect. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set an estimate of the total samples that will be encoded. + * This is merely an estimate and may be set to \c 0 if unknown. + * This value will be written to the STREAMINFO block before encoding, + * and can remove the need for the caller to rewrite the value later + * if the value is known before encoding. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value); + +/** Set the metadata blocks to be emitted to the stream before encoding. + * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an + * array of pointers to metadata blocks. The array is non-const since + * the encoder may need to change the \a is_last flag inside them, and + * in some cases update seek point offsets. Otherwise, the encoder will + * not modify or free the blocks. It is up to the caller to free the + * metadata blocks after encoding finishes. + * + * \note + * The encoder stores only copies of the pointers in the \a metadata array; + * the metadata blocks themselves must survive at least until after + * FLAC__stream_encoder_finish() returns. Do not free the blocks until then. + * + * \note + * The STREAMINFO block is always written and no STREAMINFO block may + * occur in the supplied array. + * + * \note + * By default the encoder does not create a SEEKTABLE. If one is supplied + * in the \a metadata array, but the client has specified that it does not + * support seeking, then the SEEKTABLE will be written verbatim. However + * by itself this is not very useful as the client will not know the stream + * offsets for the seekpoints ahead of time. In order to get a proper + * seektable the client must support seeking. See next note. + * + * \note + * SEEKTABLE blocks are handled specially. Since you will not know + * the values for the seek point stream offsets, you should pass in + * a SEEKTABLE 'template', that is, a SEEKTABLE object with the + * required sample numbers (or placeholder points), with \c 0 for the + * \a frame_samples and \a stream_offset fields for each point. If the + * client has specified that it supports seeking by providing a seek + * callback to FLAC__stream_encoder_init_stream() or both seek AND read + * callback to FLAC__stream_encoder_init_ogg_stream() (or by using + * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE()), + * then while it is encoding the encoder will fill the stream offsets in + * for you and when encoding is finished, it will seek back and write the + * real values into the SEEKTABLE block in the stream. There are helper + * routines for manipulating seektable template blocks; see metadata.h: + * FLAC__metadata_object_seektable_template_*(). If the client does + * not support seeking, the SEEKTABLE will have inaccurate offsets which + * will slow down or remove the ability to seek in the FLAC stream. + * + * \note + * The encoder instance \b will modify the first \c SEEKTABLE block + * as it transforms the template to a valid seektable while encoding, + * but it is still up to the caller to free all metadata blocks after + * encoding. + * + * \note + * A VORBIS_COMMENT block may be supplied. The vendor string in it + * will be ignored. libFLAC will use it's own vendor string. libFLAC + * will not modify the passed-in VORBIS_COMMENT's vendor string, it + * will simply write it's own into the stream. If no VORBIS_COMMENT + * block is present in the \a metadata array, libFLAC will write an + * empty one, containing only the vendor string. + * + * \note The Ogg FLAC mapping requires that the VORBIS_COMMENT block be + * the second metadata block of the stream. The encoder already supplies + * the STREAMINFO block automatically. If \a metadata does not contain a + * VORBIS_COMMENT block, the encoder will supply that too. Otherwise, if + * \a metadata does contain a VORBIS_COMMENT block and it is not the + * first, the init function will reorder \a metadata by moving the + * VORBIS_COMMENT block to the front; the relative ordering of the other + * blocks will remain as they were. + * + * \note The Ogg FLAC mapping limits the number of metadata blocks per + * stream to \c 65535. If \a num_blocks exceeds this the function will + * return \c false. + * + * \default \c NULL, 0 + * \param encoder An encoder instance to set. + * \param metadata See above. + * \param num_blocks See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + * \c false if the encoder is already initialized, or if + * \a num_blocks > 65535 if encoding to Ogg FLAC, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); + +/** Get the current encoder state. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderState + * The current encoder state. + */ +FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder); + +/** Get the state of the verify stream decoder. + * Useful when the stream encoder state is + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamDecoderState + * The verify stream decoder state. + */ +FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder); + +/** Get the current encoder state as a C string. + * This version automatically resolves + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the + * verify decoder's state. + * + * \param encoder A encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval const char * + * The encoder state as a C string. Do not modify the contents. + */ +FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder); + +/** Get relevant values about the nature of a verify decoder error. + * Useful when the stream encoder state is + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should + * be addresses in which the stats will be returned, or NULL if value + * is not desired. + * + * \param encoder An encoder instance to query. + * \param absolute_sample The absolute sample number of the mismatch. + * \param frame_number The number of the frame in which the mismatch occurred. + * \param channel The channel in which the mismatch occurred. + * \param sample The number of the sample (relative to the frame) in + * which the mismatch occurred. + * \param expected The expected value for the sample in question. + * \param got The actual value returned by the decoder. + * \assert + * \code encoder != NULL \endcode + */ +FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); + +/** Get the "verify" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_verify(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder); + +/** Get the <A HREF="../format.html#subset>Subset</A> flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_streamable_subset(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder); + +/** Get the number of input channels being processed. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_channels(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder); + +/** Get the input sample resolution setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_bits_per_sample(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder); + +/** Get the input sample rate setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_sample_rate(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder); + +/** Get the blocksize setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_blocksize(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder); + +/** Get the "mid/side stereo coding" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_get_do_mid_side_stereo(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder); + +/** Get the "adaptive mid/side switching" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_loose_mid_side_stereo(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder); + +/** Get the maximum LPC order setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_max_lpc_order(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder); + +/** Get the quantized linear predictor coefficient precision setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_qlp_coeff_precision(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder); + +/** Get the qlp coefficient precision search flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_do_qlp_coeff_prec_search(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder); + +/** Get the "escape coding" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_do_escape_coding(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder); + +/** Get the exhaustive model search flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_do_exhaustive_model_search(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder); + +/** Get the minimum residual partition order setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_min_residual_partition_order(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder); + +/** Get maximum residual partition order setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_max_residual_partition_order(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder); + +/** Get the Rice parameter search distance setting. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval unsigned + * See FLAC__stream_encoder_set_rice_parameter_search_dist(). + */ +FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder); + +/** Get the previously set estimate of the total samples to be encoded. + * The encoder merely mimics back the value given to + * FLAC__stream_encoder_set_total_samples_estimate() since it has no + * other way of knowing how many samples the client will encode. + * + * \param encoder An encoder instance to set. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__uint64 + * See FLAC__stream_encoder_get_total_samples_estimate(). + */ +FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder); + +/** Initialize the encoder instance to encode native FLAC streams. + * + * This flavor of initialization sets up the encoder to encode to a + * native FLAC stream. I/O is performed via callbacks to the client. + * For encoding to a plain file via filename or open \c FILE*, + * FLAC__stream_encoder_init_file() and FLAC__stream_encoder_init_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * The call to FLAC__stream_encoder_init_stream() currently will also + * immediately call the write callback several times, once with the \c fLaC + * signature, and once for each encoded metadata block. + * + * \param encoder An uninitialized encoder instance. + * \param write_callback See FLAC__StreamEncoderWriteCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamEncoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. The encoder uses seeking to go back + * and write some some stream statistics to the + * STREAMINFO block; this is recommended but not + * necessary to create a valid FLAC stream. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param tell_callback See FLAC__StreamEncoderTellCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is \c NULL then + * this argument will be ignored. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. If the client provides a seek callback, + * this function is not necessary as the encoder + * will automatically seek back and update the + * STREAMINFO block. It may also be \c NULL if the + * client does not support seeking, since it will + * have no way of going back to update the + * STREAMINFO. However the client can still supply + * a callback if it would like to know the details + * from the STREAMINFO. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data); + +/** Initialize the encoder instance to encode Ogg FLAC streams. + * + * This flavor of initialization sets up the encoder to encode to a FLAC + * stream in an Ogg container. I/O is performed via callbacks to the + * client. For encoding to a plain file via filename or open \c FILE*, + * FLAC__stream_encoder_init_ogg_file() and FLAC__stream_encoder_init_ogg_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * The call to FLAC__stream_encoder_init_ogg_stream() currently will also + * immediately call the write callback several times to write the metadata + * packets. + * + * \param encoder An uninitialized encoder instance. + * \param read_callback See FLAC__StreamEncoderReadCallback. This + * pointer must not be \c NULL if \a seek_callback + * is non-NULL since they are both needed to be + * able to write data back to the Ogg FLAC stream + * in the post-encode phase. + * \param write_callback See FLAC__StreamEncoderWriteCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamEncoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. The encoder uses seeking to go back + * and write some some stream statistics to the + * STREAMINFO block; this is recommended but not + * necessary to create a valid FLAC stream. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param tell_callback See FLAC__StreamEncoderTellCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is \c NULL then + * this argument will be ignored. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the encoder. + * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. If the client provides a seek callback, + * this function is not necessary as the encoder + * will automatically seek back and update the + * STREAMINFO block. It may also be \c NULL if the + * client does not support seeking, since it will + * have no way of going back to update the + * STREAMINFO. However the client can still supply + * a callback if it would like to know the details + * from the STREAMINFO. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderReadCallback read_callback, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data); + +/** Initialize the encoder instance to encode native FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a + * plain native FLAC file. For non-stdio streams, you must use + * FLAC__stream_encoder_init_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param file An open file. The file should have been opened + * with mode \c "w+b" and rewound. The file + * becomes owned by the encoder and should not be + * manipulated by the client while encoding. + * Unless \a file is \c stdout, it will be closed + * when FLAC__stream_encoder_finish() is called. + * Note however that a proper SEEKTABLE cannot be + * created when encoding to \c stdout since it is + * not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Initialize the encoder instance to encode Ogg FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a + * plain Ogg FLAC file. For non-stdio streams, you must use + * FLAC__stream_encoder_init_ogg_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param file An open file. The file should have been opened + * with mode \c "w+b" and rewound. The file + * becomes owned by the encoder and should not be + * manipulated by the client while encoding. + * Unless \a file is \c stdout, it will be closed + * when FLAC__stream_encoder_finish() is called. + * Note however that a proper SEEKTABLE cannot be + * created when encoding to \c stdout since it is + * not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Initialize the encoder instance to encode native FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a plain + * FLAC file. If POSIX fopen() semantics are not sufficient (for example, + * with Unicode filenames on Windows), you must use + * FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param filename The name of the file to encode to. The file will + * be opened with fopen(). Use \c NULL to encode to + * \c stdout. Note however that a proper SEEKTABLE + * cannot be created when encoding to \c stdout since + * it is not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Initialize the encoder instance to encode Ogg FLAC files. + * + * This flavor of initialization sets up the encoder to encode to a plain + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient (for example, + * with Unicode filenames on Windows), you must use + * FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_encoder_new() and + * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() + * or FLAC__stream_encoder_process_interleaved(). + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \param filename The name of the file to encode to. The file will + * be opened with fopen(). Use \c NULL to encode to + * \c stdout. Note however that a proper SEEKTABLE + * cannot be created when encoding to \c stdout since + * it is not seekable. + * \param progress_callback See FLAC__StreamEncoderProgressCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderInitStatus + * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamEncoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data); + +/** Finish the encoding process. + * Flushes the encoding buffer, releases resources, resets the encoder + * settings to their defaults, and returns the encoder state to + * FLAC__STREAM_ENCODER_UNINITIALIZED. Note that this can generate + * one or more write callbacks before returning, and will generate + * a metadata callback. + * + * Note that in the course of processing the last frame, errors can + * occur, so the caller should be sure to check the return value to + * ensure the file was encoded properly. + * + * In the event of a prematurely-terminated encode, it is not strictly + * necessary to call this immediately before FLAC__stream_encoder_delete() + * but it is good practice to match every FLAC__stream_encoder_init_*() + * with a FLAC__stream_encoder_finish(). + * + * \param encoder An uninitialized encoder instance. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if an error occurred processing the last frame; or if verify + * mode is set (see FLAC__stream_encoder_set_verify()), there was a + * verify mismatch; else \c true. If \c false, caller should check the + * state with FLAC__stream_encoder_get_state() for more information + * about the error. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder); + +/** Submit data for encoding. + * This version allows you to supply the input data via an array of + * pointers, each pointer pointing to an array of \a samples samples + * representing one channel. The samples need not be block-aligned, + * but each channel should have the same number of samples. Each sample + * should be a signed integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the + * resolution is 16 bits per sample, the samples should all be in the + * range [-32768,32767]. + * + * For applications where channel order is important, channels must + * follow the order as described in the + * <A HREF="../format.html#frame_header">frame header</A>. + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of pointers to each channel's signal. + * \param samples The number of samples in one channel. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__stream_encoder_get_state() to see what + * went wrong. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); + +/** Submit data for encoding. + * This version allows you to supply the input data where the channels + * are interleaved into a single array (i.e. channel0_sample0, + * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). + * The samples need not be block-aligned but they must be + * sample-aligned, i.e. the first value should be channel0_sample0 + * and the last value channelN_sampleM. Each sample should be a signed + * integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the + * resolution is 16 bits per sample, the samples should all be in the + * range [-32768,32767]. + * + * For applications where channel order is important, channels must + * follow the order as described in the + * <A HREF="../format.html#frame_header">frame header</A>. + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of channel-interleaved data (see above). + * \param samples The number of samples in one channel, the same as for + * FLAC__stream_encoder_process(). For example, if + * encoding two channels, \c 1000 \a samples corresponds + * to a \a buffer of 2000 values. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__stream_encoder_get_state() to see what + * went wrong. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/Makefile.am b/deps/flac-1.3.2/include/Makefile.am new file mode 100644 index 0000000..ce567b8 --- /dev/null +++ b/deps/flac-1.3.2/include/Makefile.am @@ -0,0 +1,23 @@ +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under different licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. + +if FLaC__WITH_CPPLIBS +CPPLIBS_DIRS = FLAC++ +endif + +SUBDIRS = FLAC $(CPPLIBS_DIRS) share test_libs_common diff --git a/deps/flac-1.3.2/include/Makefile.in b/deps/flac-1.3.2/include/Makefile.in new file mode 100644 index 0000000..87df4ce --- /dev/null +++ b/deps/flac-1.3.2/include/Makefile.in @@ -0,0 +1,679 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under different licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-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 \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = FLAC FLAC++ share test_libs_common +am__DIST_COMMON = $(srcdir)/Makefile.in +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_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@FLaC__WITH_CPPLIBS_TRUE@CPPLIBS_DIRS = FLAC++ +SUBDIRS = FLAC $(CPPLIBS_DIRS) share test_libs_common +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 include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/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 + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + 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" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + 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; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + 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 +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 Makefile +distclean-am: clean-am distclean-generic 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 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: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean 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-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-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/include/share/Makefile.am b/deps/flac-1.3.2/include/share/Makefile.am new file mode 100644 index 0000000..2d8ca50 --- /dev/null +++ b/deps/flac-1.3.2/include/share/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = grabbag + +EXTRA_DIST = \ + alloc.h \ + compat.h \ + endswap.h \ + getopt.h \ + grabbag.h \ + macros.h \ + private.h \ + replaygain_analysis.h \ + replaygain_synthesis.h \ + safe_str.h \ + utf8.h \ + win_utf8_io.h \ + windows_unicode_filenames.h diff --git a/deps/flac-1.3.2/include/share/Makefile.in b/deps/flac-1.3.2/include/share/Makefile.in new file mode 100644 index 0000000..8dd7f52 --- /dev/null +++ b/deps/flac-1.3.2/include/share/Makefile.in @@ -0,0 +1,675 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/share +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-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 \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +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_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = grabbag +EXTRA_DIST = \ + alloc.h \ + compat.h \ + endswap.h \ + getopt.h \ + grabbag.h \ + macros.h \ + private.h \ + replaygain_analysis.h \ + replaygain_synthesis.h \ + safe_str.h \ + utf8.h \ + win_utf8_io.h \ + windows_unicode_filenames.h + +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 include/share/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/share/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 + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + 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" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + 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; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + 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 +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 Makefile +distclean-am: clean-am distclean-generic 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 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: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean 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-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-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/include/share/alloc.h b/deps/flac-1.3.2/include/share/alloc.h new file mode 100644 index 0000000..914de9b --- /dev/null +++ b/deps/flac-1.3.2/include/share/alloc.h @@ -0,0 +1,219 @@ +/* alloc - Convenience routines for safely allocating memory + * Copyright (C) 2007-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__SHARE__ALLOC_H +#define FLAC__SHARE__ALLOC_H + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early + * before #including this file, otherwise SIZE_MAX might not be defined + */ + +#include <limits.h> /* for SIZE_MAX */ +#if HAVE_STDINT_H +#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ +#endif +#include <stdlib.h> /* for size_t, malloc(), etc */ +#include "share/compat.h" + +#ifndef SIZE_MAX +# ifndef SIZE_T_MAX +# ifdef _MSC_VER +# ifdef _WIN64 +# define SIZE_T_MAX FLAC__U64L(0xffffffffffffffff) +# else +# define SIZE_T_MAX 0xffffffff +# endif +# else +# error +# endif +# endif +# define SIZE_MAX SIZE_T_MAX +#endif + +/* avoid malloc()ing 0 bytes, see: + * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 +*/ +static inline void *safe_malloc_(size_t size) +{ + /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(!size) + size++; + return malloc(size); +} + +static inline void *safe_calloc_(size_t nmemb, size_t size) +{ + if(!nmemb || !size) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + return calloc(nmemb, size); +} + +/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ + +static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) +{ + size2 += size1; + if(size2 < size1) + return 0; + return safe_malloc_(size2); +} + +static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + return safe_malloc_(size3); +} + +static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + size4 += size3; + if(size4 < size3) + return 0; + return safe_malloc_(size4); +} + +void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; + +static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) +{ + if(!size1 || !size2 || !size3) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(size1 > SIZE_MAX / size2) + return 0; + size1 *= size2; + if(size1 > SIZE_MAX / size3) + return 0; + return malloc(size1*size3); +} + +/* size1*size2 + size3 */ +static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) +{ + if(!size1 || !size2) + return safe_malloc_(size3); + if(size1 > SIZE_MAX / size2) + return 0; + return safe_malloc_add_2op_(size1*size2, size3); +} + +/* size1 * (size2 + size3) */ +static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) +{ + if(!size1 || (!size2 && !size3)) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + size2 += size3; + if(size2 < size3) + return 0; + if(size1 > SIZE_MAX / size2) + return 0; + return malloc(size1*size2); +} + +static inline void *safe_realloc_(void *ptr, size_t size) +{ + void *oldptr = ptr; + void *newptr = realloc(ptr, size); + if(size > 0 && newptr == 0) + free(oldptr); + return newptr; +} +static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) +{ + size2 += size1; + if(size2 < size1) { + free(ptr); + return 0; + } + return realloc(ptr, size2); +} + +static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + return realloc(ptr, size3); +} + +static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + size4 += size3; + if(size4 < size3) + return 0; + return realloc(ptr, size4); +} + +static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) +{ + if(!size1 || !size2) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + if(size1 > SIZE_MAX / size2) + return 0; + return safe_realloc_(ptr, size1*size2); +} + +/* size1 * (size2 + size3) */ +static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) +{ + if(!size1 || (!size2 && !size3)) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + size2 += size3; + if(size2 < size3) + return 0; + return safe_realloc_mul_2op_(ptr, size1, size2); +} + +#endif diff --git a/deps/flac-1.3.2/include/share/compat.h b/deps/flac-1.3.2/include/share/compat.h new file mode 100644 index 0000000..2083f3a --- /dev/null +++ b/deps/flac-1.3.2/include/share/compat.h @@ -0,0 +1,209 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2012-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +/* This is the prefered location of all CPP hackery to make $random_compiler + * work like something approaching a C99 (or maybe more accurately GNU99) + * compiler. + * + * It is assumed that this header will be included after "config.h". + */ + +#ifndef FLAC__SHARE__COMPAT_H +#define FLAC__SHARE__COMPAT_H + +#if defined _WIN32 && !defined __CYGWIN__ +/* where MSVC puts unlink() */ +# include <io.h> +#else +# include <unistd.h> +#endif + +#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ +#include <sys/types.h> /* for off_t */ +#define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */ +#if !defined __MINGW32__ +#define fseeko _fseeki64 +#define ftello _ftelli64 +#else /* MinGW */ +#if !defined(HAVE_FSEEKO) +#define fseeko fseeko64 +#define ftello ftello64 +#endif +#endif +#else +#define FLAC__off_t off_t +#endif + +#if HAVE_INTTYPES_H +#define __STDC_FORMAT_MACROS +#include <inttypes.h> +#endif + +#if defined(_MSC_VER) +#define strtoll _strtoi64 +#define strtoull _strtoui64 +#endif + +#if defined(_MSC_VER) +#define inline __inline +#endif + +#if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64) +/* MSVS generates VERY slow 32-bit code with __restrict */ +#define flac_restrict __restrict +#elif defined __GNUC__ +#define flac_restrict __restrict__ +#else +#define flac_restrict +#endif + +#define FLAC__U64L(x) x##ULL + +#if defined _MSC_VER || defined __MINGW32__ +#define FLAC__STRCASECMP _stricmp +#define FLAC__STRNCASECMP _strnicmp +#elif defined __BORLANDC__ +#define FLAC__STRCASECMP stricmp +#define FLAC__STRNCASECMP strnicmp +#else +#define FLAC__STRCASECMP strcasecmp +#define FLAC__STRNCASECMP strncasecmp +#endif + +#if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__ +#include <io.h> /* for _setmode(), chmod() */ +#include <fcntl.h> /* for _O_BINARY */ +#else +#include <unistd.h> /* for chown(), unlink() */ +#endif + +#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ +#if defined __BORLANDC__ +#include <utime.h> /* for utime() */ +#else +#include <sys/utime.h> /* for utime() */ +#endif +#else +#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ +#include <utime.h> /* for utime() */ +#endif + +#if defined _MSC_VER +# if _MSC_VER >= 1800 +# include <inttypes.h> +# elif _MSC_VER >= 1600 +/* Visual Studio 2010 has decent C99 support */ +# include <stdint.h> +# define PRIu64 "llu" +# define PRId64 "lld" +# define PRIx64 "llx" +# else +# include <limits.h> +# ifndef UINT32_MAX +# define UINT32_MAX _UI32_MAX +# endif + typedef unsigned __int64 uint64_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int8 uint8_t; + typedef __int64 int64_t; + typedef __int32 int32_t; + typedef __int16 int16_t; + typedef __int8 int8_t; +# define PRIu64 "I64u" +# define PRId64 "I64d" +# define PRIx64 "I64x" +# endif +#endif /* defined _MSC_VER */ + +#ifdef _WIN32 +/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */ + +#include "share/win_utf8_io.h" +#define flac_printf printf_utf8 +#define flac_fprintf fprintf_utf8 +#define flac_vfprintf vfprintf_utf8 + +#include "share/windows_unicode_filenames.h" +#define flac_fopen flac_internal_fopen_utf8 +#define flac_chmod flac_internal_chmod_utf8 +#define flac_utime flac_internal_utime_utf8 +#define flac_unlink flac_internal_unlink_utf8 +#define flac_rename flac_internal_rename_utf8 +#define flac_stat flac_internal_stat64_utf8 + +#else + +#define flac_printf printf +#define flac_fprintf fprintf +#define flac_vfprintf vfprintf + +#define flac_fopen fopen +#define flac_chmod chmod +#define flac_utime utime +#define flac_unlink unlink +#define flac_rename rename +#define flac_stat stat + +#endif + +#ifdef _WIN32 +#define flac_stat_s __stat64 /* stat struct */ +#define flac_fstat _fstat64 +#else +#define flac_stat_s stat /* stat struct */ +#define flac_fstat fstat +#endif + +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* FLAC needs to compile and work correctly on systems with a normal ISO C99 + * snprintf as well as Microsoft Visual Studio which has an non-standards + * conformant snprint_s function. + * + * This function wraps the MS version to behave more like the ISO version. + */ +#include <stdarg.h> +#ifdef __cplusplus +extern "C" { +#endif +int flac_snprintf(char *str, size_t size, const char *fmt, ...); +int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va); +#ifdef __cplusplus +}; +#endif + +#endif /* FLAC__SHARE__COMPAT_H */ diff --git a/deps/flac-1.3.2/include/share/endswap.h b/deps/flac-1.3.2/include/share/endswap.h new file mode 100644 index 0000000..9088a74 --- /dev/null +++ b/deps/flac-1.3.2/include/share/endswap.h @@ -0,0 +1,84 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2012-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +/* It is assumed that this header will be included after "config.h". */ + +#if HAVE_BSWAP32 /* GCC and Clang */ + +/* GCC prior to 4.8 didn't provide bswap16 on x86_64 */ +#if ! HAVE_BSWAP16 +static inline unsigned short __builtin_bswap16(unsigned short a) +{ + return (a<<8)|(a>>8); +} +#endif + +#define ENDSWAP_16(x) (__builtin_bswap16 (x)) +#define ENDSWAP_32(x) (__builtin_bswap32 (x)) +#define ENDSWAP_64(x) (__builtin_bswap64 (x)) + +#elif defined _MSC_VER /* Windows */ + +#include <stdlib.h> + +#define ENDSWAP_16(x) (_byteswap_ushort (x)) +#define ENDSWAP_32(x) (_byteswap_ulong (x)) +#define ENDSWAP_64(x) (_byteswap_uint64 (x)) + +#elif defined HAVE_BYTESWAP_H /* Linux */ + +#include <byteswap.h> + +#define ENDSWAP_16(x) (bswap_16 (x)) +#define ENDSWAP_32(x) (bswap_32 (x)) +#define ENDSWAP_64(x) (bswap_64 (x)) + +#else + +#define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8)) +#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24)) +#define ENDSWAP_64(x) ((ENDSWAP_32(((x) >> 32) & 0xFFFFFFFF)) | (ENDSWAP_32((x) & 0xFFFFFFFF) << 32)) + +#endif + + +/* Host to little-endian byte swapping (for MD5 calculation) */ +#if CPU_IS_BIG_ENDIAN + +#define H2LE_16(x) ENDSWAP_16 (x) +#define H2LE_32(x) ENDSWAP_32 (x) + +#else + +#define H2LE_16(x) (x) +#define H2LE_32(x) (x) + +#endif diff --git a/deps/flac-1.3.2/include/share/getopt.h b/deps/flac-1.3.2/include/share/getopt.h new file mode 100644 index 0000000..66aced0 --- /dev/null +++ b/deps/flac-1.3.2/include/share/getopt.h @@ -0,0 +1,184 @@ +/* + NOTE: + I cannot get the vanilla getopt code to work (i.e. compile only what + is needed and not duplicate symbols found in the standard library) + on all the platforms that FLAC supports. In particular the gating + of code with the ELIDE_CODE #define is not accurate enough on systems + that are POSIX but not glibc. If someone has a patch that works on + GNU/Linux, Darwin, AND Solaris please submit it on the project page: + https://sourceforge.net/p/flac/patches/ + + In the meantime I have munged the global symbols and removed gates + around code, while at the same time trying to touch the original as + little as possible. +*/ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#ifndef SHARE__GETOPT_H +#define SHARE__GETOPT_H + +/*[JEC] was:#ifndef __need_getopt*/ +/*[JEC] was:# define _GETOPT_H 1*/ +/*[JEC] was:#endif*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `share__getopt' to the caller. + When `share__getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *share__optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `share__getopt'. + + On entry to `share__getopt', zero means this is the first call; initialize. + + When `share__getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `share__optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int share__optind; + +/* Callers store zero here to inhibit the error message `share__getopt' prints + for unrecognized options. */ + +extern int share__opterr; + +/* Set to an option character which was unrecognized. */ + +extern int share__optopt; + +/*[JEC] was:#ifndef __need_getopt */ +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to share__getopt_long or share__getopt_long_only is a vector + of `struct share__option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + share__no_argument (or 0) if the option does not take an argument, + share__required_argument (or 1) if the option requires an argument, + share__optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `share__optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `share__getopt' + returns the contents of the `val' field. */ + +struct share__option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct share__option'. */ + +# define share__no_argument 0 +# define share__required_argument 1 +# define share__optional_argument 2 +/*[JEC] was:#endif*/ /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `share__optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `share__optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `share__getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `share__getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `share__getopt'. */ + +/*[JEC] was:#if defined __STDC__ && __STDC__*/ +/*[JEC] was:# ifdef __GNU_LIBRARY__*/ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int share__getopt (int argc, char *const *argv, const char *shortopts); +/*[JEC] was:# else*/ /* not __GNU_LIBRARY__ */ +/*[JEC] was:extern int getopt ();*/ +/*[JEC] was:# endif*/ /* __GNU_LIBRARY__ */ + +/*[JEC] was:# ifndef __need_getopt*/ +extern int share__getopt_long (int argc, char *const *argv, const char *shortopts, + const struct share__option *longopts, int *longind); +extern int share__getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct share__option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int share___getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct share__option *longopts, int *longind, + int long_only); +/*[JEC] was:# endif*/ +/*[JEC] was:#else*/ /* not __STDC__ */ +/*[JEC] was:extern int getopt ();*/ +/*[JEC] was:# ifndef __need_getopt*/ +/*[JEC] was:extern int getopt_long ();*/ +/*[JEC] was:extern int getopt_long_only ();*/ + +/*[JEC] was:extern int _getopt_internal ();*/ +/*[JEC] was:# endif*/ +/*[JEC] was:#endif*/ /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +/*[JEC] was:#undef __need_getopt*/ + +#endif /* getopt.h */ diff --git a/deps/flac-1.3.2/include/share/grabbag.h b/deps/flac-1.3.2/include/share/grabbag.h new file mode 100644 index 0000000..92ec998 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag.h @@ -0,0 +1,30 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SHARE__GRABBAG_H +#define SHARE__GRABBAG_H + +/* These can't be included by themselves, only from within grabbag.h */ +#include "grabbag/cuesheet.h" +#include "grabbag/file.h" +#include "grabbag/picture.h" +#include "grabbag/replaygain.h" +#include "grabbag/seektable.h" + +#endif diff --git a/deps/flac-1.3.2/include/share/grabbag/Makefile.am b/deps/flac-1.3.2/include/share/grabbag/Makefile.am new file mode 100644 index 0000000..22baa15 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = \ + cuesheet.h \ + file.h \ + picture.h \ + replaygain.h \ + seektable.h diff --git a/deps/flac-1.3.2/include/share/grabbag/Makefile.in b/deps/flac-1.3.2/include/share/grabbag/Makefile.in new file mode 100644 index 0000000..ae8363d --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/Makefile.in @@ -0,0 +1,486 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/share/grabbag +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + cuesheet.h \ + file.h \ + picture.h \ + replaygain.h \ + seektable.h + +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 include/share/grabbag/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/share/grabbag/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 +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +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 +installdirs: +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-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 -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: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am 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-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 \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/include/share/grabbag/cuesheet.h b/deps/flac-1.3.2/include/share/grabbag/cuesheet.h new file mode 100644 index 0000000..b465ae6 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/cuesheet.h @@ -0,0 +1,43 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This .h cannot be included by itself; #include "share/grabbag.h" instead. */ + +#ifndef GRABBAG__CUESHEET_H +#define GRABBAG__CUESHEET_H + +#include <stdio.h> +#include "FLAC/metadata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames); +void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames); + +FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset); + +void grabbag__cuesheet_emit(FILE *file, const FLAC__StreamMetadata *cuesheet, const char *file_reference); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/share/grabbag/file.h b/deps/flac-1.3.2/include/share/grabbag/file.h new file mode 100644 index 0000000..b3f4148 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/file.h @@ -0,0 +1,65 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Convenience routines for manipulating files */ + +/* This .h cannot be included by itself; #include "share/grabbag.h" instead. */ + +#ifndef GRABAG__FILE_H +#define GRABAG__FILE_H + +/* needed because of off_t */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/types.h> /* for off_t */ +#include <stdio.h> /* for FILE */ +#include "FLAC/ordinals.h" +#include "share/compat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void grabbag__file_copy_metadata(const char *srcpath, const char *destpath); +FLAC__off_t grabbag__file_get_filesize(const char *srcpath); +const char *grabbag__file_get_basename(const char *srcpath); + +/* read_only == false means "make file writable by user" + * read_only == true means "make file read-only for everyone" + */ +FLAC__bool grabbag__file_change_stats(const char *filename, FLAC__bool read_only); + +/* returns true iff stat() succeeds for both files and they have the same device and inode. */ +/* on windows, uses GetFileInformationByHandle() to compare */ +FLAC__bool grabbag__file_are_same(const char *f1, const char *f2); + +/* attempts to make writable before unlinking */ +FLAC__bool grabbag__file_remove_file(const char *filename); + +/* these will forcibly set stdin/stdout to binary mode (for OSes that require it) */ +FILE *grabbag__file_get_binary_stdin(void); +FILE *grabbag__file_get_binary_stdout(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/share/grabbag/picture.h b/deps/flac-1.3.2/include/share/grabbag/picture.h new file mode 100644 index 0000000..ea308f1 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/picture.h @@ -0,0 +1,54 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2006-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* This .h cannot be included by itself; #include "share/grabbag.h" instead. */ + +#ifndef GRABBAG__PICTURE_H +#define GRABBAG__PICTURE_H + +#include "FLAC/metadata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* spec should be of the form "[TYPE]|MIME_TYPE|[DESCRIPTION]|[WIDTHxHEIGHTxDEPTH[/COLORS]]|FILE", e.g. + * "|image/jpeg|||cover.jpg" + * "4|image/jpeg||300x300x24|backcover.jpg" + * "|image/png|description|300x300x24/71|cover.png" + * "-->|image/gif||300x300x24/71|http://blah.blah.blah/cover.gif" + * + * empty type means default to FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER + * empty resolution spec means to get from the file (cannot get used with "-->" linked images) + * spec and error_message must not be NULL + */ +FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, const char **error_message); + +typedef struct PictureResolution +{ uint32_t width, height, depth, colors ; +} PictureResolution ; + +FLAC__StreamMetadata *grabbag__picture_from_specification(int type, const char *mime_type, const char * description, + const PictureResolution * res, const char * filepath, const char **error_message); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/share/grabbag/replaygain.h b/deps/flac-1.3.2/include/share/grabbag/replaygain.h new file mode 100644 index 0000000..faa3272 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/replaygain.h @@ -0,0 +1,73 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * This wraps the replaygain_analysis lib, which is LGPL. This wrapper + * allows analysis of different input resolutions by automatically + * scaling the input signal + */ + +/* This .h cannot be included by itself; #include "share/grabbag.h" instead. */ + +#ifndef GRABBAG__REPLAYGAIN_H +#define GRABBAG__REPLAYGAIN_H + +#include "FLAC/metadata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED; + +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS; /* = "REPLAYGAIN_REFERENCE_LOUDNESS" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN; /* = "REPLAYGAIN_TRACK_GAIN" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK; /* = "REPLAYGAIN_TRACK_PEAK" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN; /* = "REPLAYGAIN_ALBUM_GAIN" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK; /* = "REPLAYGAIN_ALBUM_PEAK" */ + +FLAC__bool grabbag__replaygain_is_valid_sample_frequency(unsigned sample_frequency); + +FLAC__bool grabbag__replaygain_init(unsigned sample_frequency); + +/* 'bps' must be valid for FLAC, i.e. >=4 and <= 32 */ +FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__bool is_stereo, unsigned bps, unsigned samples); + +void grabbag__replaygain_get_album(float *gain, float *peak); +void grabbag__replaygain_get_title(float *gain, float *peak); + +/* These three functions return an error string on error, or NULL if successful */ +const char *grabbag__replaygain_analyze_file(const char *filename, float *title_gain, float *title_peak); +const char *grabbag__replaygain_store_to_vorbiscomment(FLAC__StreamMetadata *block, float album_gain, float album_peak, float title_gain, float title_peak); +const char *grabbag__replaygain_store_to_vorbiscomment_reference(FLAC__StreamMetadata *block); +const char *grabbag__replaygain_store_to_vorbiscomment_album(FLAC__StreamMetadata *block, float album_gain, float album_peak); +const char *grabbag__replaygain_store_to_vorbiscomment_title(FLAC__StreamMetadata *block, float title_gain, float title_peak); +const char *grabbag__replaygain_store_to_file(const char *filename, float album_gain, float album_peak, float title_gain, float title_peak, FLAC__bool preserve_modtime); +const char *grabbag__replaygain_store_to_file_reference(const char *filename, FLAC__bool preserve_modtime); +const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime); +const char *grabbag__replaygain_store_to_file_title(const char *filename, float title_gain, float title_peak, FLAC__bool preserve_modtime); + +FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak); +double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/share/grabbag/seektable.h b/deps/flac-1.3.2/include/share/grabbag/seektable.h new file mode 100644 index 0000000..ac294a3 --- /dev/null +++ b/deps/flac-1.3.2/include/share/grabbag/seektable.h @@ -0,0 +1,39 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Convenience routines for working with seek tables */ + +/* This .h cannot be included by itself; #include "share/grabbag.h" instead. */ + +#ifndef GRABAG__SEEKTABLE_H +#define GRABAG__SEEKTABLE_H + +#include "FLAC/format.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FLAC__bool grabbag__seektable_convert_specification_to_template(const char *spec, FLAC__bool only_explicit_placeholders, FLAC__uint64 total_samples_to_encode, unsigned sample_rate, FLAC__StreamMetadata *seektable_template, FLAC__bool *spec_has_real_points); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/flac-1.3.2/include/share/macros.h b/deps/flac-1.3.2/include/share/macros.h new file mode 100644 index 0000000..20b3ea5 --- /dev/null +++ b/deps/flac-1.3.2/include/share/macros.h @@ -0,0 +1,45 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#include <errno.h> + +/* FLAC_CHECK_RETURN : Check the return value of the provided function and + * print an error message if it fails (ie returns a value < 0). + * + * Ideally, a library should not print anything, but this macro is only used + * for things that extremely unlikely to fail, like `chown` to a previoulsy + * saved `uid`. + */ + +#define FLAC_CHECK_RETURN(x) \ + { if ((x) < 0) \ + fprintf (stderr, "%s : %s\n", #x, strerror (errno)) ; \ + } diff --git a/deps/flac-1.3.2/include/share/private.h b/deps/flac-1.3.2/include/share/private.h new file mode 100644 index 0000000..f7e3b85 --- /dev/null +++ b/deps/flac-1.3.2/include/share/private.h @@ -0,0 +1,45 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__SHARE__PRIVATE_H +#define FLAC__SHARE__PRIVATE_H + +/* + * Unpublished debug routines from libFLAC> This should not be used from any + * client code other than code shipped with the FLAC sources. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder); + +#endif /* FLAC__SHARE__PRIVATE_H */ diff --git a/deps/flac-1.3.2/include/share/replaygain_analysis.h b/deps/flac-1.3.2/include/share/replaygain_analysis.h new file mode 100644 index 0000000..f06a9b2 --- /dev/null +++ b/deps/flac-1.3.2/include/share/replaygain_analysis.h @@ -0,0 +1,59 @@ +/* + * ReplayGainAnalysis - analyzes input samples and give the recommended dB change + * Copyright (C) 2001 David Robinson and Glen Sawyer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * concept and filter values by David Robinson (David@Robinson.org) + * -- blame him if you think the idea is flawed + * coding by Glen Sawyer (glensawyer@hotmail.com) 442 N 700 E, Provo, UT 84606 USA + * -- blame him if you think this runs too slowly, or the coding is otherwise flawed + * minor cosmetic tweaks to integrate with FLAC by Josh Coalson + * + * For an explanation of the concepts and the basic algorithms involved, go to: + * http://www.replaygain.org/ + */ + +#ifndef GAIN_ANALYSIS_H +#define GAIN_ANALYSIS_H + +#include <stddef.h> + +#define GAIN_NOT_ENOUGH_SAMPLES -24601 +#define GAIN_ANALYSIS_ERROR 0 +#define GAIN_ANALYSIS_OK 1 + +#define INIT_GAIN_ANALYSIS_ERROR 0 +#define INIT_GAIN_ANALYSIS_OK 1 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float flac_float_t; /* Type used for filtering */ + +extern flac_float_t ReplayGainReferenceLoudness; /* in dB SPL, currently == 89.0 */ + +int InitGainAnalysis ( long samplefreq ); +int ValidGainFrequency ( long samplefreq ); +int AnalyzeSamples ( const flac_float_t* left_samples, const flac_float_t* right_samples, size_t num_samples, int num_channels ); +flac_float_t GetTitleGain ( void ); +flac_float_t GetAlbumGain ( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* GAIN_ANALYSIS_H */ diff --git a/deps/flac-1.3.2/include/share/replaygain_synthesis.h b/deps/flac-1.3.2/include/share/replaygain_synthesis.h new file mode 100644 index 0000000..5f4c3ff --- /dev/null +++ b/deps/flac-1.3.2/include/share/replaygain_synthesis.h @@ -0,0 +1,52 @@ +/* replaygain_synthesis - Routines for applying ReplayGain to a signal + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FLAC__SHARE__REPLAYGAIN_SYNTHESIS_H +#define FLAC__SHARE__REPLAYGAIN_SYNTHESIS_H + +#include <stdlib.h> /* for size_t */ +#include "FLAC/format.h" + +#define FLAC_SHARE__MAX_SUPPORTED_CHANNELS FLAC__MAX_CHANNELS + +typedef enum { + NOISE_SHAPING_NONE = 0, + NOISE_SHAPING_LOW = 1, + NOISE_SHAPING_MEDIUM = 2, + NOISE_SHAPING_HIGH = 3 +} NoiseShaping; + +typedef struct { + const float* FilterCoeff; + FLAC__uint64 Mask; + double Add; + float Dither; + float ErrorHistory [FLAC_SHARE__MAX_SUPPORTED_CHANNELS] [16]; /* 16th order Noise shaping */ + float DitherHistory [FLAC_SHARE__MAX_SUPPORTED_CHANNELS] [16]; + int LastRandomNumber [FLAC_SHARE__MAX_SUPPORTED_CHANNELS]; + unsigned LastHistoryIndex; + NoiseShaping ShapingType; +} DitherContext; + +void FLAC__replaygain_synthesis__init_dither_context(DitherContext *dither, int bits, int shapingtype); + +/* scale = (float) pow(10., (double)replaygain * 0.05); */ +size_t FLAC__replaygain_synthesis__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, FLAC__bool unsigned_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const double scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context); + +#endif diff --git a/deps/flac-1.3.2/include/share/safe_str.h b/deps/flac-1.3.2/include/share/safe_str.h new file mode 100644 index 0000000..eb974c5 --- /dev/null +++ b/deps/flac-1.3.2/include/share/safe_str.h @@ -0,0 +1,69 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +/* Safe string handling functions to replace things like strcpy, strncpy, + * strcat, strncat etc. + * All of these functions guarantee a correctly NUL terminated string but + * the string may be truncated if the destination buffer was too short. + */ + +#ifndef FLAC__SHARE_SAFE_STR_H +#define FLAC__SHARE_SAFE_STR_H + +static inline char * +safe_strncat(char *dest, const char *src, size_t dest_size) +{ + char * ret; + + if (dest_size < 1) + return dest; + + ret = strncat(dest, src, dest_size - strlen (dest)); + dest [dest_size - 1] = 0; + + return ret; +} + +static inline char * +safe_strncpy(char *dest, const char *src, size_t dest_size) +{ + char * ret; + + if (dest_size < 1) + return dest; + + ret = strncpy(dest, src, dest_size); + dest [dest_size - 1] = 0; + + return ret; +} + +#endif /* FLAC__SHARE_SAFE_STR_H */ diff --git a/deps/flac-1.3.2/include/share/utf8.h b/deps/flac-1.3.2/include/share/utf8.h new file mode 100644 index 0000000..7d6650d --- /dev/null +++ b/deps/flac-1.3.2/include/share/utf8.h @@ -0,0 +1,25 @@ +#ifndef SHARE__UTF8_H +#define SHARE__UTF8_H + +/* + * Convert a string between UTF-8 and the locale's charset. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * + * If the locale's charset is not set explicitly then it is + * obtained using nl_langinfo(CODESET), where available, the + * environment variable CHARSET, or assumed to be US-ASCII. + * + * Return value of conversion functions: + * + * -1 : memory allocation failed + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ + +int utf8_encode(const char *from, char **to); +int utf8_decode(const char *from, char **to); + +#endif diff --git a/deps/flac-1.3.2/include/share/win_utf8_io.h b/deps/flac-1.3.2/include/share/win_utf8_io.h new file mode 100644 index 0000000..13fd118 --- /dev/null +++ b/deps/flac-1.3.2/include/share/win_utf8_io.h @@ -0,0 +1,58 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef _WIN32 + +#ifndef flac__win_utf8_io_h +#define flac__win_utf8_io_h + +#include <stdio.h> +#include <stdarg.h> + +#ifdef __cplusplus +extern "C" { +#endif + +size_t strlen_utf8(const char *str); +int win_get_console_width(void); + +int get_utf8_argv(int *argc, char ***argv); + +int printf_utf8(const char *format, ...); +int fprintf_utf8(FILE *stream, const char *format, ...); +int vfprintf_utf8(FILE *stream, const char *format, va_list argptr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif diff --git a/deps/flac-1.3.2/include/share/windows_unicode_filenames.h b/deps/flac-1.3.2/include/share/windows_unicode_filenames.h new file mode 100644 index 0000000..86820ca --- /dev/null +++ b/deps/flac-1.3.2/include/share/windows_unicode_filenames.h @@ -0,0 +1,67 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef _WIN32 + +#ifndef flac__windows_unicode_filenames_h +#define flac__windows_unicode_filenames_h + +#include <stdio.h> +#include <sys/stat.h> +#include <sys/utime.h> +#include "FLAC/ordinals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void flac_internal_set_utf8_filenames(FLAC__bool flag); +FLAC__bool flac_internal_get_utf8_filenames(void); +#define flac_set_utf8_filenames flac_internal_set_utf8_filenames +#define flac_get_utf8_filenames flac_internal_get_utf8_filenames + +FILE* flac_internal_fopen_utf8(const char *filename, const char *mode); +int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer); +int flac_internal_chmod_utf8(const char *filename, int pmode); +int flac_internal_utime_utf8(const char *filename, struct utimbuf *times); +int flac_internal_unlink_utf8(const char *filename); +int flac_internal_rename_utf8(const char *oldname, const char *newname); + +#include <windows.h> +HANDLE WINAPI flac_internal_CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); +#define CreateFile_utf8 flac_internal_CreateFile_utf8 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif diff --git a/deps/flac-1.3.2/include/test_libs_common/Makefile.am b/deps/flac-1.3.2/include/test_libs_common/Makefile.am new file mode 100644 index 0000000..af82b4d --- /dev/null +++ b/deps/flac-1.3.2/include/test_libs_common/Makefile.am @@ -0,0 +1,5 @@ +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = \ + file_utils_flac.h \ + metadata_utils.h diff --git a/deps/flac-1.3.2/include/test_libs_common/Makefile.in b/deps/flac-1.3.2/include/test_libs_common/Makefile.in new file mode 100644 index 0000000..4a3b0c6 --- /dev/null +++ b/deps/flac-1.3.2/include/test_libs_common/Makefile.in @@ -0,0 +1,483 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/test_libs_common +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + file_utils_flac.h \ + metadata_utils.h + +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 include/test_libs_common/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/test_libs_common/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 +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +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 +installdirs: +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-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 -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: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am 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-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 \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/include/test_libs_common/file_utils_flac.h b/deps/flac-1.3.2/include/test_libs_common/file_utils_flac.h new file mode 100644 index 0000000..8b809b8 --- /dev/null +++ b/deps/flac-1.3.2/include/test_libs_common/file_utils_flac.h @@ -0,0 +1,36 @@ +/* test_libFLAC - Unit tester for libFLAC + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef FLAC__TEST_LIBFLAC_FILE_UTILS_H +#define FLAC__TEST_LIBFLAC_FILE_UTILS_H + +/* needed because of off_t */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "FLAC/format.h" +#include <sys/types.h> /* for off_t */ +#include "share/compat.h" + +extern const long file_utils__ogg_serial_number; + +FLAC__bool file_utils__generate_flacfile(FLAC__bool is_ogg, const char *output_filename, FLAC__off_t *output_filesize, unsigned length, const FLAC__StreamMetadata *streaminfo, FLAC__StreamMetadata **metadata, unsigned num_metadata); + +#endif diff --git a/deps/flac-1.3.2/include/test_libs_common/metadata_utils.h b/deps/flac-1.3.2/include/test_libs_common/metadata_utils.h new file mode 100644 index 0000000..ad0f6f5 --- /dev/null +++ b/deps/flac-1.3.2/include/test_libs_common/metadata_utils.h @@ -0,0 +1,71 @@ +/* test_libFLAC - Unit tester for libFLAC + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef FLAC__TEST_LIBS_COMMON_METADATA_UTILS_H +#define FLAC__TEST_LIBS_COMMON_METADATA_UTILS_H + +/* + * These are not tests, just utility functions used by the metadata tests + */ + +#include "FLAC/format.h" + +FLAC__bool mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo *block, const FLAC__StreamMetadata_StreamInfo *blockcopy); + +FLAC__bool mutils__compare_block_data_padding(const FLAC__StreamMetadata_Padding *block, const FLAC__StreamMetadata_Padding *blockcopy, unsigned block_length); + +FLAC__bool mutils__compare_block_data_application(const FLAC__StreamMetadata_Application *block, const FLAC__StreamMetadata_Application *blockcopy, unsigned block_length); + +FLAC__bool mutils__compare_block_data_seektable(const FLAC__StreamMetadata_SeekTable *block, const FLAC__StreamMetadata_SeekTable *blockcopy); + +FLAC__bool mutils__compare_block_data_vorbiscomment(const FLAC__StreamMetadata_VorbisComment *block, const FLAC__StreamMetadata_VorbisComment *blockcopy); + +FLAC__bool mutils__compare_block_data_cuesheet(const FLAC__StreamMetadata_CueSheet *block, const FLAC__StreamMetadata_CueSheet *blockcopy); + +FLAC__bool mutils__compare_block_data_picture(const FLAC__StreamMetadata_Picture *block, const FLAC__StreamMetadata_Picture *blockcopy); + +FLAC__bool mutils__compare_block_data_unknown(const FLAC__StreamMetadata_Unknown *block, const FLAC__StreamMetadata_Unknown *blockcopy, unsigned block_length); + +FLAC__bool mutils__compare_block(const FLAC__StreamMetadata *block, const FLAC__StreamMetadata *blockcopy); + +void mutils__init_metadata_blocks( + FLAC__StreamMetadata *streaminfo, + FLAC__StreamMetadata *padding, + FLAC__StreamMetadata *seektable, + FLAC__StreamMetadata *application1, + FLAC__StreamMetadata *application2, + FLAC__StreamMetadata *vorbiscomment, + FLAC__StreamMetadata *cuesheet, + FLAC__StreamMetadata *picture, + FLAC__StreamMetadata *unknown +); + +void mutils__free_metadata_blocks( + FLAC__StreamMetadata *streaminfo, + FLAC__StreamMetadata *padding, + FLAC__StreamMetadata *seektable, + FLAC__StreamMetadata *application1, + FLAC__StreamMetadata *application2, + FLAC__StreamMetadata *vorbiscomment, + FLAC__StreamMetadata *cuesheet, + FLAC__StreamMetadata *picture, + FLAC__StreamMetadata *unknown +); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/Makefile.am b/deps/flac-1.3.2/src/libFLAC/Makefile.am new file mode 100644 index 0000000..863f7f9 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/Makefile.am @@ -0,0 +1,135 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +lib_LTLIBRARIES = libFLAC.la +noinst_LTLIBRARIES = libFLAC-static.la +if DEBUG +DEBUGCFLAGS = -DFLAC__OVERFLOW_DETECT +endif + +# FIXME: The following logic should be part of configure, not of Makefile.am + +if FLaC__CPU_PPC +if FLaC__SYS_DARWIN +CPUCFLAGS = -faltivec +else +CPUCFLAGS = +if FLaC__USE_ALTIVEC +CPUCFLAGS += -maltivec -mabi=altivec +endif +endif +endif + +AM_CFLAGS = $(DEBUGCFLAGS) $(CPUCFLAGS) @OGG_CFLAGS@ + +if FLaC__NO_ASM +else +if FLaC__CPU_IA32 +if FLaC__HAS_NASM +ARCH_SUBDIRS = ia32 +LOCAL_EXTRA_LIBADD = ia32/libFLAC-asm.la +endif +endif +endif + +libFLAC_la_LIBADD = $(LOCAL_EXTRA_LIBADD) @OGG_LIBS@ -lm + +SUBDIRS = $(ARCH_SUBDIRS) include . + +m4datadir = $(datadir)/aclocal +m4data_DATA = libFLAC.m4 + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = flac.pc + +EXTRA_DIST = \ + Makefile.lite \ + flac.pc.in \ + libFLAC_dynamic.vcproj \ + libFLAC_dynamic.vcxproj \ + libFLAC_dynamic.vcxproj.filters \ + libFLAC_static.vcproj \ + libFLAC_static.vcxproj \ + libFLAC_static.vcxproj.filters \ + libFLAC.m4 \ + windows_unicode_filenames.c + +if OS_IS_WINDOWS +windows_unicode_compat = windows_unicode_filenames.c +endif + +if FLaC__HAS_OGG +extra_ogg_sources = \ + ogg_decoder_aspect.c \ + ogg_encoder_aspect.c \ + ogg_helper.c \ + ogg_mapping.c +endif + +# see 'http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning' for numbering convention +libFLAC_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 11:0:3 $(LOCAL_EXTRA_LDFLAGS) + +libFLAC_sources = \ + bitmath.c \ + bitreader.c \ + bitwriter.c \ + cpu.c \ + crc.c \ + fixed.c \ + fixed_intrin_sse2.c \ + fixed_intrin_ssse3.c \ + float.c \ + format.c \ + lpc.c \ + lpc_intrin_sse.c \ + lpc_intrin_sse2.c \ + lpc_intrin_sse41.c \ + lpc_intrin_avx2.c \ + md5.c \ + memory.c \ + metadata_iterators.c \ + metadata_object.c \ + stream_decoder.c \ + stream_encoder.c \ + stream_encoder_intrin_sse2.c \ + stream_encoder_intrin_ssse3.c \ + stream_encoder_intrin_avx2.c \ + stream_encoder_framing.c \ + window.c \ + $(windows_unicode_compat) \ + $(extra_ogg_sources) + +libFLAC_la_SOURCES = $(libFLAC_sources) + +# needed for test_libFLAC +libFLAC_static_la_LIBADD = $(LOCAL_EXTRA_LIBADD) +libFLAC_static_la_SOURCES = $(libFLAC_sources) diff --git a/deps/flac-1.3.2/src/libFLAC/Makefile.in b/deps/flac-1.3.2/src/libFLAC/Makefile.in new file mode 100644 index 0000000..36f6b48 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/Makefile.in @@ -0,0 +1,1042 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@@FLaC__USE_ALTIVEC_TRUE@am__append_1 = -maltivec -mabi=altivec +subdir = src/libFLAC +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = flac.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)$(m4datadir)" \ + "$(DESTDIR)$(pkgconfigdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +libFLAC_static_la_DEPENDENCIES = $(LOCAL_EXTRA_LIBADD) +am__libFLAC_static_la_SOURCES_DIST = bitmath.c bitreader.c bitwriter.c \ + cpu.c crc.c fixed.c fixed_intrin_sse2.c fixed_intrin_ssse3.c \ + float.c format.c lpc.c lpc_intrin_sse.c lpc_intrin_sse2.c \ + lpc_intrin_sse41.c lpc_intrin_avx2.c md5.c memory.c \ + metadata_iterators.c metadata_object.c stream_decoder.c \ + stream_encoder.c stream_encoder_intrin_sse2.c \ + stream_encoder_intrin_ssse3.c stream_encoder_intrin_avx2.c \ + stream_encoder_framing.c window.c windows_unicode_filenames.c \ + ogg_decoder_aspect.c ogg_encoder_aspect.c ogg_helper.c \ + ogg_mapping.c +@OS_IS_WINDOWS_TRUE@am__objects_1 = windows_unicode_filenames.lo +@FLaC__HAS_OGG_TRUE@am__objects_2 = ogg_decoder_aspect.lo \ +@FLaC__HAS_OGG_TRUE@ ogg_encoder_aspect.lo ogg_helper.lo \ +@FLaC__HAS_OGG_TRUE@ ogg_mapping.lo +am__objects_3 = bitmath.lo bitreader.lo bitwriter.lo cpu.lo crc.lo \ + fixed.lo fixed_intrin_sse2.lo fixed_intrin_ssse3.lo float.lo \ + format.lo lpc.lo lpc_intrin_sse.lo lpc_intrin_sse2.lo \ + lpc_intrin_sse41.lo lpc_intrin_avx2.lo md5.lo memory.lo \ + metadata_iterators.lo metadata_object.lo stream_decoder.lo \ + stream_encoder.lo stream_encoder_intrin_sse2.lo \ + stream_encoder_intrin_ssse3.lo stream_encoder_intrin_avx2.lo \ + stream_encoder_framing.lo window.lo $(am__objects_1) \ + $(am__objects_2) +am_libFLAC_static_la_OBJECTS = $(am__objects_3) +libFLAC_static_la_OBJECTS = $(am_libFLAC_static_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libFLAC_la_DEPENDENCIES = $(LOCAL_EXTRA_LIBADD) +am__libFLAC_la_SOURCES_DIST = bitmath.c bitreader.c bitwriter.c cpu.c \ + crc.c fixed.c fixed_intrin_sse2.c fixed_intrin_ssse3.c float.c \ + format.c lpc.c lpc_intrin_sse.c lpc_intrin_sse2.c \ + lpc_intrin_sse41.c lpc_intrin_avx2.c md5.c memory.c \ + metadata_iterators.c metadata_object.c stream_decoder.c \ + stream_encoder.c stream_encoder_intrin_sse2.c \ + stream_encoder_intrin_ssse3.c stream_encoder_intrin_avx2.c \ + stream_encoder_framing.c window.c windows_unicode_filenames.c \ + ogg_decoder_aspect.c ogg_encoder_aspect.c ogg_helper.c \ + ogg_mapping.c +am_libFLAC_la_OBJECTS = $(am__objects_3) +libFLAC_la_OBJECTS = $(am_libFLAC_la_OBJECTS) +libFLAC_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libFLAC_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__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_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libFLAC_static_la_SOURCES) $(libFLAC_la_SOURCES) +DIST_SOURCES = $(am__libFLAC_static_la_SOURCES_DIST) \ + $(am__libFLAC_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-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 \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(m4data_DATA) $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = ia32 include . +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/flac.pc.in \ + $(top_srcdir)/depcomp +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_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +lib_LTLIBRARIES = libFLAC.la +noinst_LTLIBRARIES = libFLAC-static.la +@DEBUG_TRUE@DEBUGCFLAGS = -DFLAC__OVERFLOW_DETECT +@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@CPUCFLAGS = \ +@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@ $(am__append_1) + +# FIXME: The following logic should be part of configure, not of Makefile.am +@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@CPUCFLAGS = -faltivec \ +@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@ $(am__append_1) +AM_CFLAGS = $(DEBUGCFLAGS) $(CPUCFLAGS) @OGG_CFLAGS@ +@FLaC__CPU_IA32_TRUE@@FLaC__HAS_NASM_TRUE@@FLaC__NO_ASM_FALSE@ARCH_SUBDIRS = ia32 +@FLaC__CPU_IA32_TRUE@@FLaC__HAS_NASM_TRUE@@FLaC__NO_ASM_FALSE@LOCAL_EXTRA_LIBADD = ia32/libFLAC-asm.la +libFLAC_la_LIBADD = $(LOCAL_EXTRA_LIBADD) @OGG_LIBS@ -lm +SUBDIRS = $(ARCH_SUBDIRS) include . +m4datadir = $(datadir)/aclocal +m4data_DATA = libFLAC.m4 +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = flac.pc +EXTRA_DIST = \ + Makefile.lite \ + flac.pc.in \ + libFLAC_dynamic.vcproj \ + libFLAC_dynamic.vcxproj \ + libFLAC_dynamic.vcxproj.filters \ + libFLAC_static.vcproj \ + libFLAC_static.vcxproj \ + libFLAC_static.vcxproj.filters \ + libFLAC.m4 \ + windows_unicode_filenames.c + +@OS_IS_WINDOWS_TRUE@windows_unicode_compat = windows_unicode_filenames.c +@FLaC__HAS_OGG_TRUE@extra_ogg_sources = \ +@FLaC__HAS_OGG_TRUE@ ogg_decoder_aspect.c \ +@FLaC__HAS_OGG_TRUE@ ogg_encoder_aspect.c \ +@FLaC__HAS_OGG_TRUE@ ogg_helper.c \ +@FLaC__HAS_OGG_TRUE@ ogg_mapping.c + + +# see 'http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning' for numbering convention +libFLAC_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 11:0:3 $(LOCAL_EXTRA_LDFLAGS) +libFLAC_sources = \ + bitmath.c \ + bitreader.c \ + bitwriter.c \ + cpu.c \ + crc.c \ + fixed.c \ + fixed_intrin_sse2.c \ + fixed_intrin_ssse3.c \ + float.c \ + format.c \ + lpc.c \ + lpc_intrin_sse.c \ + lpc_intrin_sse2.c \ + lpc_intrin_sse41.c \ + lpc_intrin_avx2.c \ + md5.c \ + memory.c \ + metadata_iterators.c \ + metadata_object.c \ + stream_decoder.c \ + stream_encoder.c \ + stream_encoder_intrin_sse2.c \ + stream_encoder_intrin_ssse3.c \ + stream_encoder_intrin_avx2.c \ + stream_encoder_framing.c \ + window.c \ + $(windows_unicode_compat) \ + $(extra_ogg_sources) + +libFLAC_la_SOURCES = $(libFLAC_sources) + +# needed for test_libFLAC +libFLAC_static_la_LIBADD = $(LOCAL_EXTRA_LIBADD) +libFLAC_static_la_SOURCES = $(libFLAC_sources) +all: all-recursive + +.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/libFLAC/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libFLAC/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): +flac.pc: $(top_builddir)/config.status $(srcdir)/flac.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + 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)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libFLAC-static.la: $(libFLAC_static_la_OBJECTS) $(libFLAC_static_la_DEPENDENCIES) $(EXTRA_libFLAC_static_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libFLAC_static_la_OBJECTS) $(libFLAC_static_la_LIBADD) $(LIBS) + +libFLAC.la: $(libFLAC_la_OBJECTS) $(libFLAC_la_DEPENDENCIES) $(EXTRA_libFLAC_la_DEPENDENCIES) + $(AM_V_CCLD)$(libFLAC_la_LINK) -rpath $(libdir) $(libFLAC_la_OBJECTS) $(libFLAC_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitmath.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitreader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitwriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed_intrin_sse2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed_intrin_ssse3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc_intrin_avx2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc_intrin_sse.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc_intrin_sse2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc_intrin_sse41.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_iterators.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metadata_object.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ogg_decoder_aspect.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ogg_encoder_aspect.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ogg_helper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ogg_mapping.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_decoder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_encoder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_encoder_framing.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_encoder_intrin_avx2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_encoder_intrin_sse2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_encoder_intrin_ssse3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windows_unicode_filenames.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-m4dataDATA: $(m4data_DATA) + @$(NORMAL_INSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \ + fi; \ + 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)$(m4datadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ + done + +uninstall-m4dataDATA: + @$(NORMAL_UNINSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + 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) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + 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" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + 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; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + 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) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgconfigdir)"; 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 \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -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-m4dataDATA 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 -rf ./$(DEPDIR) + -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-libLTLIBRARIES uninstall-m4dataDATA \ + uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-m4dataDATA \ + 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-am uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-m4dataDATA uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/src/libFLAC/Makefile.lite b/deps/flac-1.3.2/src/libFLAC/Makefile.lite new file mode 100644 index 0000000..aa3e175 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/Makefile.lite @@ -0,0 +1,110 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +# +# GNU makefile +# + +topdir = ../.. + +ifeq ($(OS),Darwin) + EXPLICIT_LIBS = $(OGG_EXPLICIT_LIBS) -lm +else + LIBS = $(OGG_LIBS) -lm +endif + +ifeq ($(findstring Windows,$(OS)),Windows) + WIN_UNICODE_COMPAT = windows_unicode_filenames.c +endif + +LIB_NAME = libFLAC +ifeq ($(PROC),ppc) + DEFINES = -DFLAC__CPU_PPC -DFLAC__USE_ALTIVEC -DFLAC__ALIGN_MALLOC_DATA +else +ifeq ($(OS),Solaris) + DEFINES = -DFLAC__NO_ASM -DFLAC__ALIGN_MALLOC_DATA +else +ifeq ($(PROC),i386) + DEFINES = -DFLAC__CPU_IA32 -DFLAC__HAS_NASM -DFLAC__ALIGN_MALLOC_DATA +else + DEFINES = -DFLAC__ALIGN_MALLOC_DATA +endif +endif +endif +INCLUDES = -I./include -I$(topdir)/include $(OGG_INCLUDES) +DEBUG_CFLAGS = -DFLAC__OVERFLOW_DETECT + +ifeq ($(PROC),i386) +SRCS_NASM = \ + ia32/cpu_asm.nasm \ + ia32/fixed_asm.nasm \ + ia32/lpc_asm.nasm +endif + +OGG_SRCS_C = \ + ogg_decoder_aspect.c \ + ogg_encoder_aspect.c \ + ogg_helper.c \ + ogg_mapping.c + +SRCS_C = \ + bitmath.c \ + bitreader.c \ + bitwriter.c \ + cpu.c \ + crc.c \ + fixed.c \ + fixed_intrin_sse2.c \ + fixed_intrin_ssse3.c \ + float.c \ + format.c \ + lpc.c \ + lpc_intrin_sse.c \ + lpc_intrin_sse2.c \ + lpc_intrin_sse41.c \ + lpc_intrin_avx2.c \ + md5.c \ + memory.c \ + metadata_iterators.c \ + metadata_object.c \ + stream_decoder.c \ + stream_encoder.c \ + stream_encoder_intrin_sse2.c \ + stream_encoder_intrin_ssse3.c \ + stream_encoder_intrin_avx2.c \ + stream_encoder_framing.c \ + window.c \ + $(WIN_UNICODE_COMPAT) \ + $(OGG_SRCS) + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/libFLAC/bitmath.c b/deps/flac-1.3.2/src/libFLAC/bitmath.c new file mode 100644 index 0000000..b3d797d --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/bitmath.c @@ -0,0 +1,73 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/bitmath.h" + +/* An example of what FLAC__bitmath_silog2() computes: + * + * silog2(-10) = 5 + * silog2(- 9) = 5 + * silog2(- 8) = 4 + * silog2(- 7) = 4 + * silog2(- 6) = 4 + * silog2(- 5) = 4 + * silog2(- 4) = 3 + * silog2(- 3) = 3 + * silog2(- 2) = 2 + * silog2(- 1) = 2 + * silog2( 0) = 0 + * silog2( 1) = 2 + * silog2( 2) = 3 + * silog2( 3) = 3 + * silog2( 4) = 4 + * silog2( 5) = 4 + * silog2( 6) = 4 + * silog2( 7) = 4 + * silog2( 8) = 5 + * silog2( 9) = 5 + * silog2( 10) = 5 + */ +unsigned FLAC__bitmath_silog2(FLAC__int64 v) +{ + if(v == 0) + return 0; + + if(v == -1) + return 2; + + v = (v < 0) ? (-(v+1)) : v; + return FLAC__bitmath_ilog2_wide(v)+2; +} diff --git a/deps/flac-1.3.2/src/libFLAC/bitreader.c b/deps/flac-1.3.2/src/libFLAC/bitreader.c new file mode 100644 index 0000000..ab62d41 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/bitreader.c @@ -0,0 +1,1087 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include "private/bitmath.h" +#include "private/bitreader.h" +#include "private/crc.h" +#include "private/macros.h" +#include "FLAC/assert.h" +#include "share/compat.h" +#include "share/endswap.h" + +/* Things should be fastest when this matches the machine word size */ +/* WATCHOUT: if you change this you must also change the following #defines down to COUNT_ZERO_MSBS2 below to match */ +/* WATCHOUT: there are a few places where the code will not work unless brword is >= 32 bits wide */ +/* also, some sections currently only have fast versions for 4 or 8 bytes per word */ + +#if (ENABLE_64_BIT_WORDS == 0) + +typedef FLAC__uint32 brword; +#define FLAC__BYTES_PER_WORD 4 /* sizeof brword */ +#define FLAC__BITS_PER_WORD 32 +#define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) +/* SWAP_BE_WORD_TO_HOST swaps bytes in a brword (which is always big-endian) if necessary to match host byte order */ +#if WORDS_BIGENDIAN +#define SWAP_BE_WORD_TO_HOST(x) (x) +#else +#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x) +#endif +/* counts the # of zero MSBs in a word */ +#define COUNT_ZERO_MSBS(word) FLAC__clz_uint32(word) +#define COUNT_ZERO_MSBS2(word) FLAC__clz2_uint32(word) + +#else + +typedef FLAC__uint64 brword; +#define FLAC__BYTES_PER_WORD 8 /* sizeof brword */ +#define FLAC__BITS_PER_WORD 64 +#define FLAC__WORD_ALL_ONES ((FLAC__uint64)FLAC__U64L(0xffffffffffffffff)) +/* SWAP_BE_WORD_TO_HOST swaps bytes in a brword (which is always big-endian) if necessary to match host byte order */ +#if WORDS_BIGENDIAN +#define SWAP_BE_WORD_TO_HOST(x) (x) +#else +#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_64(x) +#endif +/* counts the # of zero MSBs in a word */ +#define COUNT_ZERO_MSBS(word) FLAC__clz_uint64(word) +#define COUNT_ZERO_MSBS2(word) FLAC__clz2_uint64(word) + +#endif + +/* + * This should be at least twice as large as the largest number of words + * required to represent any 'number' (in any encoding) you are going to + * read. With FLAC this is on the order of maybe a few hundred bits. + * If the buffer is smaller than that, the decoder won't be able to read + * in a whole number that is in a variable length encoding (e.g. Rice). + * But to be practical it should be at least 1K bytes. + * + * Increase this number to decrease the number of read callbacks, at the + * expense of using more memory. Or decrease for the reverse effect, + * keeping in mind the limit from the first paragraph. The optimal size + * also depends on the CPU cache size and other factors; some twiddling + * may be necessary to squeeze out the best performance. + */ +static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */ + +struct FLAC__BitReader { + /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ + /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ + brword *buffer; + unsigned capacity; /* in words */ + unsigned words; /* # of completed words in buffer */ + unsigned bytes; /* # of bytes in incomplete word at buffer[words] */ + unsigned consumed_words; /* #words ... */ + unsigned consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */ + unsigned read_crc16; /* the running frame CRC */ + unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */ + FLAC__BitReaderReadCallback read_callback; + void *client_data; +}; + +static inline void crc16_update_word_(FLAC__BitReader *br, brword word) +{ + register unsigned crc = br->read_crc16; +#if FLAC__BYTES_PER_WORD == 4 + switch(br->crc16_align) { + case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 24), crc); + case 8: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 16) & 0xff), crc); + case 16: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 8) & 0xff), crc); + case 24: br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)(word & 0xff), crc); + } +#elif FLAC__BYTES_PER_WORD == 8 + switch(br->crc16_align) { + case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 56), crc); + case 8: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 48) & 0xff), crc); + case 16: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 40) & 0xff), crc); + case 24: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 32) & 0xff), crc); + case 32: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 24) & 0xff), crc); + case 40: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 16) & 0xff), crc); + case 48: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 8) & 0xff), crc); + case 56: br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)(word & 0xff), crc); + } +#else + for( ; br->crc16_align < FLAC__BITS_PER_WORD; br->crc16_align += 8) + crc = FLAC__CRC16_UPDATE((unsigned)((word >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), crc); + br->read_crc16 = crc; +#endif + br->crc16_align = 0; +} + +static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) +{ + unsigned start, end; + size_t bytes; + FLAC__byte *target; + + /* first shift the unconsumed buffer data toward the front as much as possible */ + if(br->consumed_words > 0) { + start = br->consumed_words; + end = br->words + (br->bytes? 1:0); + memmove(br->buffer, br->buffer+start, FLAC__BYTES_PER_WORD * (end - start)); + + br->words -= start; + br->consumed_words = 0; + } + + /* + * set the target for reading, taking into account word alignment and endianness + */ + bytes = (br->capacity - br->words) * FLAC__BYTES_PER_WORD - br->bytes; + if(bytes == 0) + return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */ + target = ((FLAC__byte*)(br->buffer+br->words)) + br->bytes; + + /* before reading, if the existing reader looks like this (say brword is 32 bits wide) + * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified) + * buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown layed out as bytes sequentially in memory) + * buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care) + * ^^-------target, bytes=3 + * on LE machines, have to byteswap the odd tail word so nothing is + * overwritten: + */ +#if WORDS_BIGENDIAN +#else + if(br->bytes) + br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]); +#endif + + /* now it looks like: + * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 + * buffer[BE]: 11 22 33 44 55 ?? ?? ?? + * buffer[LE]: 44 33 22 11 55 ?? ?? ?? + * ^^-------target, bytes=3 + */ + + /* read in the data; note that the callback may return a smaller number of bytes */ + if(!br->read_callback(target, &bytes, br->client_data)) + return false; + + /* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client: + * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF + * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ?? + * buffer[LE]: 44 33 22 11 55 66 77 88 99 AA BB CC DD EE FF ?? + * now have to byteswap on LE machines: + */ +#if WORDS_BIGENDIAN +#else + end = (br->words*FLAC__BYTES_PER_WORD + br->bytes + (unsigned)bytes + (FLAC__BYTES_PER_WORD-1)) / FLAC__BYTES_PER_WORD; + for(start = br->words; start < end; start++) + br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]); +#endif + + /* now it looks like: + * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF + * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ?? + * buffer[LE]: 44 33 22 11 88 77 66 55 CC BB AA 99 ?? FF EE DD + * finally we'll update the reader values: + */ + end = br->words*FLAC__BYTES_PER_WORD + br->bytes + (unsigned)bytes; + br->words = end / FLAC__BYTES_PER_WORD; + br->bytes = end % FLAC__BYTES_PER_WORD; + + return true; +} + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +FLAC__BitReader *FLAC__bitreader_new(void) +{ + FLAC__BitReader *br = calloc(1, sizeof(FLAC__BitReader)); + + /* calloc() implies: + memset(br, 0, sizeof(FLAC__BitReader)); + br->buffer = 0; + br->capacity = 0; + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + br->read_callback = 0; + br->client_data = 0; + */ + return br; +} + +void FLAC__bitreader_delete(FLAC__BitReader *br) +{ + FLAC__ASSERT(0 != br); + + FLAC__bitreader_free(br); + free(br); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd) +{ + FLAC__ASSERT(0 != br); + + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY; + br->buffer = malloc(sizeof(brword) * br->capacity); + if(br->buffer == 0) + return false; + br->read_callback = rcb; + br->client_data = cd; + + return true; +} + +void FLAC__bitreader_free(FLAC__BitReader *br) +{ + FLAC__ASSERT(0 != br); + + if(0 != br->buffer) + free(br->buffer); + br->buffer = 0; + br->capacity = 0; + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + br->read_callback = 0; + br->client_data = 0; +} + +FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br) +{ + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + return true; +} + +void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out) +{ + unsigned i, j; + if(br == 0) { + fprintf(out, "bitreader is NULL\n"); + } + else { + fprintf(out, "bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u\n", br->capacity, br->words, br->bytes, br->consumed_words, br->consumed_bits); + + for(i = 0; i < br->words; i++) { + fprintf(out, "%08X: ", i); + for(j = 0; j < FLAC__BITS_PER_WORD; j++) + if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) + fprintf(out, "."); + else + fprintf(out, "%01u", br->buffer[i] & ((brword)1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); + fprintf(out, "\n"); + } + if(br->bytes > 0) { + fprintf(out, "%08X: ", i); + for(j = 0; j < br->bytes*8; j++) + if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) + fprintf(out, "."); + else + fprintf(out, "%01u", br->buffer[i] & ((brword)1 << (br->bytes*8-j-1)) ? 1:0); + fprintf(out, "\n"); + } + } +} + +void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed) +{ + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT((br->consumed_bits & 7) == 0); + + br->read_crc16 = (unsigned)seed; + br->crc16_align = br->consumed_bits; +} + +FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br) +{ + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT((br->consumed_bits & 7) == 0); + FLAC__ASSERT(br->crc16_align <= br->consumed_bits); + + /* CRC any tail bytes in a partially-consumed word */ + if(br->consumed_bits) { + const brword tail = br->buffer[br->consumed_words]; + for( ; br->crc16_align < br->consumed_bits; br->crc16_align += 8) + br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)((tail >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), br->read_crc16); + } + return br->read_crc16; +} + +inline FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br) +{ + return ((br->consumed_bits & 7) == 0); +} + +inline unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br) +{ + return 8 - (br->consumed_bits & 7); +} + +inline unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br) +{ + return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits; +} + +FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits) +{ + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + FLAC__ASSERT(bits <= 32); + FLAC__ASSERT((br->capacity*FLAC__BITS_PER_WORD) * 2 >= bits); + FLAC__ASSERT(br->consumed_words <= br->words); + + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + + if(bits == 0) { /* OPT: investigate if this can ever happen, maybe change to assertion */ + *val = 0; + return true; + } + + while((br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits < bits) { + if(!bitreader_read_from_client_(br)) + return false; + } + if(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ + /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */ + if(br->consumed_bits) { + /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ + const unsigned n = FLAC__BITS_PER_WORD - br->consumed_bits; + const brword word = br->buffer[br->consumed_words]; + if(bits < n) { + *val = (FLAC__uint32)((word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits)); /* The result has <= 32 non-zero bits */ + br->consumed_bits += bits; + return true; + } + /* (FLAC__BITS_PER_WORD - br->consumed_bits <= bits) ==> (FLAC__WORD_ALL_ONES >> br->consumed_bits) has no more than 'bits' non-zero bits */ + *val = (FLAC__uint32)(word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)); + bits -= n; + crc16_update_word_(br, word); + br->consumed_words++; + br->consumed_bits = 0; + if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */ + *val <<= bits; + *val |= (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits)); + br->consumed_bits = bits; + } + return true; + } + else { /* br->consumed_bits == 0 */ + const brword word = br->buffer[br->consumed_words]; + if(bits < FLAC__BITS_PER_WORD) { + *val = (FLAC__uint32)(word >> (FLAC__BITS_PER_WORD-bits)); + br->consumed_bits = bits; + return true; + } + /* at this point bits == FLAC__BITS_PER_WORD == 32; because of previous assertions, it can't be larger */ + *val = (FLAC__uint32)word; + crc16_update_word_(br, word); + br->consumed_words++; + return true; + } + } + else { + /* in this case we're starting our read at a partial tail word; + * the reader has guaranteed that we have at least 'bits' bits + * available to read, which makes this case simpler. + */ + /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */ + if(br->consumed_bits) { + /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ + FLAC__ASSERT(br->consumed_bits + bits <= br->bytes*8); + *val = (FLAC__uint32)((br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (FLAC__BITS_PER_WORD-br->consumed_bits-bits)); + br->consumed_bits += bits; + return true; + } + else { + *val = (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits)); + br->consumed_bits += bits; + return true; + } + } +} + +FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits) +{ + FLAC__uint32 uval, mask; + /* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */ + if(!FLAC__bitreader_read_raw_uint32(br, &uval, bits)) + return false; + /* sign-extend *val assuming it is currently bits wide. */ + /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ + mask = 1u << (bits - 1); + *val = (uval ^ mask) - mask; + return true; +} + +FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits) +{ + FLAC__uint32 hi, lo; + + if(bits > 32) { + if(!FLAC__bitreader_read_raw_uint32(br, &hi, bits-32)) + return false; + if(!FLAC__bitreader_read_raw_uint32(br, &lo, 32)) + return false; + *val = hi; + *val <<= 32; + *val |= lo; + } + else { + if(!FLAC__bitreader_read_raw_uint32(br, &lo, bits)) + return false; + *val = lo; + } + return true; +} + +inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) +{ + FLAC__uint32 x8, x32 = 0; + + /* this doesn't need to be that fast as currently it is only used for vorbis comments */ + + if(!FLAC__bitreader_read_raw_uint32(br, &x32, 8)) + return false; + + if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) + return false; + x32 |= (x8 << 8); + + if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) + return false; + x32 |= (x8 << 16); + + if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) + return false; + x32 |= (x8 << 24); + + *val = x32; + return true; +} + +FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits) +{ + /* + * OPT: a faster implementation is possible but probably not that useful + * since this is only called a couple of times in the metadata readers. + */ + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + if(bits > 0) { + const unsigned n = br->consumed_bits & 7; + unsigned m; + FLAC__uint32 x; + + if(n != 0) { + m = flac_min(8-n, bits); + if(!FLAC__bitreader_read_raw_uint32(br, &x, m)) + return false; + bits -= m; + } + m = bits / 8; + if(m > 0) { + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(br, m)) + return false; + bits %= 8; + } + if(bits > 0) { + if(!FLAC__bitreader_read_raw_uint32(br, &x, bits)) + return false; + } + } + + return true; +} + +FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals) +{ + FLAC__uint32 x; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); + + /* step 1: skip over partial head word to get word aligned */ + while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + nvals--; + } + if(0 == nvals) + return true; + /* step 2: skip whole words in chunks */ + while(nvals >= FLAC__BYTES_PER_WORD) { + if(br->consumed_words < br->words) { + br->consumed_words++; + nvals -= FLAC__BYTES_PER_WORD; + } + else if(!bitreader_read_from_client_(br)) + return false; + } + /* step 3: skip any remainder from partial tail bytes */ + while(nvals) { + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + nvals--; + } + + return true; +} + +FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals) +{ + FLAC__uint32 x; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); + + /* step 1: read from partial head word to get word aligned */ + while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + *val++ = (FLAC__byte)x; + nvals--; + } + if(0 == nvals) + return true; + /* step 2: read whole words in chunks */ + while(nvals >= FLAC__BYTES_PER_WORD) { + if(br->consumed_words < br->words) { + const brword word = br->buffer[br->consumed_words++]; +#if FLAC__BYTES_PER_WORD == 4 + val[0] = (FLAC__byte)(word >> 24); + val[1] = (FLAC__byte)(word >> 16); + val[2] = (FLAC__byte)(word >> 8); + val[3] = (FLAC__byte)word; +#elif FLAC__BYTES_PER_WORD == 8 + val[0] = (FLAC__byte)(word >> 56); + val[1] = (FLAC__byte)(word >> 48); + val[2] = (FLAC__byte)(word >> 40); + val[3] = (FLAC__byte)(word >> 32); + val[4] = (FLAC__byte)(word >> 24); + val[5] = (FLAC__byte)(word >> 16); + val[6] = (FLAC__byte)(word >> 8); + val[7] = (FLAC__byte)word; +#else + for(x = 0; x < FLAC__BYTES_PER_WORD; x++) + val[x] = (FLAC__byte)(word >> (8*(FLAC__BYTES_PER_WORD-x-1))); +#endif + val += FLAC__BYTES_PER_WORD; + nvals -= FLAC__BYTES_PER_WORD; + } + else if(!bitreader_read_from_client_(br)) + return false; + } + /* step 3: read any remainder from partial tail bytes */ + while(nvals) { + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + *val++ = (FLAC__byte)x; + nvals--; + } + + return true; +} + +FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val) +#if 0 /* slow but readable version */ +{ + unsigned bit; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + *val = 0; + while(1) { + if(!FLAC__bitreader_read_bit(br, &bit)) + return false; + if(bit) + break; + else + *val++; + } + return true; +} +#else +{ + unsigned i; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + *val = 0; + while(1) { + while(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ + brword b = br->buffer[br->consumed_words] << br->consumed_bits; + if(b) { + i = COUNT_ZERO_MSBS(b); + *val += i; + i++; + br->consumed_bits += i; + if(br->consumed_bits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(br->consumed_bits == FLAC__BITS_PER_WORD) */ + crc16_update_word_(br, br->buffer[br->consumed_words]); + br->consumed_words++; + br->consumed_bits = 0; + } + return true; + } + else { + *val += FLAC__BITS_PER_WORD - br->consumed_bits; + crc16_update_word_(br, br->buffer[br->consumed_words]); + br->consumed_words++; + br->consumed_bits = 0; + /* didn't find stop bit yet, have to keep going... */ + } + } + /* at this point we've eaten up all the whole words; have to try + * reading through any tail bytes before calling the read callback. + * this is a repeat of the above logic adjusted for the fact we + * don't have a whole word. note though if the client is feeding + * us data a byte at a time (unlikely), br->consumed_bits may not + * be zero. + */ + if(br->bytes*8 > br->consumed_bits) { + const unsigned end = br->bytes * 8; + brword b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits; + if(b) { + i = COUNT_ZERO_MSBS(b); + *val += i; + i++; + br->consumed_bits += i; + FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); + return true; + } + else { + *val += end - br->consumed_bits; + br->consumed_bits = end; + FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); + /* didn't find stop bit yet, have to keep going... */ + } + } + if(!bitreader_read_from_client_(br)) + return false; + } +} +#endif + +FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter) +{ + FLAC__uint32 lsbs = 0, msbs = 0; + unsigned uval; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT(parameter <= 31); + + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + + /* read the binary LSBs */ + if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter)) + return false; + + /* compose the value */ + uval = (msbs << parameter) | lsbs; + if(uval & 1) + *val = -((int)(uval >> 1)) - 1; + else + *val = (int)(uval >> 1); + + return true; +} + +/* this is by far the most heavily used reader call. it ain't pretty but it's fast */ +FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter) +{ + /* try and get br->consumed_words and br->consumed_bits into register; + * must remember to flush them back to *br before calling other + * bitreader functions that use them, and before returning */ + unsigned cwords, words, lsbs, msbs, x, y; + unsigned ucbits; /* keep track of the number of unconsumed bits in word */ + brword b; + int *val, *end; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + FLAC__ASSERT(parameter < 32); + /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ + + val = vals; + end = vals + nvals; + + if(parameter == 0) { + while(val < end) { + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + + *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); + } + + return true; + } + + FLAC__ASSERT(parameter > 0); + + cwords = br->consumed_words; + words = br->words; + + /* if we've not consumed up to a partial tail word... */ + if(cwords >= words) { + x = 0; + goto process_tail; + } + + ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; + b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */ + + while(val < end) { + /* read the unary MSBs and end bit */ + x = y = COUNT_ZERO_MSBS2(b); + if(x == FLAC__BITS_PER_WORD) { + x = ucbits; + do { + /* didn't find stop bit yet, have to keep going... */ + crc16_update_word_(br, br->buffer[cwords++]); + if (cwords >= words) + goto incomplete_msbs; + b = br->buffer[cwords]; + y = COUNT_ZERO_MSBS2(b); + x += y; + } while(y == FLAC__BITS_PER_WORD); + } + b <<= y; + b <<= 1; /* account for stop bit */ + ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; + msbs = x; + + /* read the binary LSBs */ + x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit unsigned */ + if(parameter <= ucbits) { + ucbits -= parameter; + b <<= parameter; + } else { + /* there are still bits left to read, they will all be in the next word */ + crc16_update_word_(br, br->buffer[cwords++]); + if (cwords >= words) + goto incomplete_lsbs; + b = br->buffer[cwords]; + ucbits += FLAC__BITS_PER_WORD - parameter; + x |= (FLAC__uint32)(b >> ucbits); + b <<= FLAC__BITS_PER_WORD - ucbits; + } + lsbs = x; + + /* compose the value */ + x = (msbs << parameter) | lsbs; + *val++ = (int)(x >> 1) ^ -(int)(x & 1); + + continue; + + /* at this point we've eaten up all the whole words */ +process_tail: + do { + if(0) { +incomplete_msbs: + br->consumed_bits = 0; + br->consumed_words = cwords; + } + + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + msbs += x; + x = ucbits = 0; + + if(0) { +incomplete_lsbs: + br->consumed_bits = 0; + br->consumed_words = cwords; + } + + /* read the binary LSBs */ + if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits)) + return false; + lsbs = x | lsbs; + + /* compose the value */ + x = (msbs << parameter) | lsbs; + *val++ = (int)(x >> 1) ^ -(int)(x & 1); + x = 0; + + cwords = br->consumed_words; + words = br->words; + ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; + b = br->buffer[cwords] << br->consumed_bits; + } while(cwords >= words && val < end); + } + + if(ucbits == 0 && cwords < words) { + /* don't leave the head word with no unconsumed bits */ + crc16_update_word_(br, br->buffer[cwords++]); + ucbits = FLAC__BITS_PER_WORD; + } + + br->consumed_bits = FLAC__BITS_PER_WORD - ucbits; + br->consumed_words = cwords; + + return true; +} + +#if 0 /* UNUSED */ +FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter) +{ + FLAC__uint32 lsbs = 0, msbs = 0; + unsigned bit, uval, k; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + k = FLAC__bitmath_ilog2(parameter); + + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + + /* read the binary LSBs */ + if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k)) + return false; + + if(parameter == 1u<<k) { + /* compose the value */ + uval = (msbs << k) | lsbs; + } + else { + unsigned d = (1 << (k+1)) - parameter; + if(lsbs >= d) { + if(!FLAC__bitreader_read_bit(br, &bit)) + return false; + lsbs <<= 1; + lsbs |= bit; + lsbs -= d; + } + /* compose the value */ + uval = msbs * parameter + lsbs; + } + + /* unfold unsigned to signed */ + if(uval & 1) + *val = -((int)(uval >> 1)) - 1; + else + *val = (int)(uval >> 1); + + return true; +} + +FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter) +{ + FLAC__uint32 lsbs, msbs = 0; + unsigned bit, k; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + k = FLAC__bitmath_ilog2(parameter); + + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + + /* read the binary LSBs */ + if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k)) + return false; + + if(parameter == 1u<<k) { + /* compose the value */ + *val = (msbs << k) | lsbs; + } + else { + unsigned d = (1 << (k+1)) - parameter; + if(lsbs >= d) { + if(!FLAC__bitreader_read_bit(br, &bit)) + return false; + lsbs <<= 1; + lsbs |= bit; + lsbs -= d; + } + /* compose the value */ + *val = msbs * parameter + lsbs; + } + + return true; +} +#endif /* UNUSED */ + +/* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */ +FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen) +{ + FLAC__uint32 v = 0; + FLAC__uint32 x; + unsigned i; + + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + if(raw) + raw[(*rawlen)++] = (FLAC__byte)x; + if(!(x & 0x80)) { /* 0xxxxxxx */ + v = x; + i = 0; + } + else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ + v = x & 0x1F; + i = 1; + } + else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ + v = x & 0x0F; + i = 2; + } + else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ + v = x & 0x07; + i = 3; + } + else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ + v = x & 0x03; + i = 4; + } + else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ + v = x & 0x01; + i = 5; + } + else { + *val = 0xffffffff; + return true; + } + for( ; i; i--) { + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + if(raw) + raw[(*rawlen)++] = (FLAC__byte)x; + if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ + *val = 0xffffffff; + return true; + } + v <<= 6; + v |= (x & 0x3F); + } + *val = v; + return true; +} + +/* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */ +FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen) +{ + FLAC__uint64 v = 0; + FLAC__uint32 x; + unsigned i; + + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + if(raw) + raw[(*rawlen)++] = (FLAC__byte)x; + if(!(x & 0x80)) { /* 0xxxxxxx */ + v = x; + i = 0; + } + else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ + v = x & 0x1F; + i = 1; + } + else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ + v = x & 0x0F; + i = 2; + } + else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ + v = x & 0x07; + i = 3; + } + else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ + v = x & 0x03; + i = 4; + } + else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ + v = x & 0x01; + i = 5; + } + else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */ + v = 0; + i = 6; + } + else { + *val = FLAC__U64L(0xffffffffffffffff); + return true; + } + for( ; i; i--) { + if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) + return false; + if(raw) + raw[(*rawlen)++] = (FLAC__byte)x; + if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ + *val = FLAC__U64L(0xffffffffffffffff); + return true; + } + v <<= 6; + v |= (x & 0x3F); + } + *val = v; + return true; +} + +/* These functions are declared inline in this file but are also callable as + * externs from elsewhere. + * According to the C99 spec, section 6.7.4, simply providing a function + * prototype in a header file without 'inline' and making the function inline + * in this file should be sufficient. + * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To + * fix that we add extern declarations here. + */ +extern FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); +extern unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); +extern unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); +extern FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); diff --git a/deps/flac-1.3.2/src/libFLAC/bitwriter.c b/deps/flac-1.3.2/src/libFLAC/bitwriter.c new file mode 100644 index 0000000..402b1c4 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/bitwriter.c @@ -0,0 +1,881 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include "private/bitwriter.h" +#include "private/crc.h" +#include "private/macros.h" +#include "FLAC/assert.h" +#include "share/alloc.h" +#include "share/compat.h" +#include "share/endswap.h" + +/* Things should be fastest when this matches the machine word size */ +/* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ +/* WATCHOUT: there are a few places where the code will not work unless bwword is >= 32 bits wide */ + +#if (ENABLE_64_BIT_WORDS == 0) + +typedef FLAC__uint32 bwword; +#define FLAC__BYTES_PER_WORD 4 /* sizeof bwword */ +#define FLAC__BITS_PER_WORD 32 +/* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ +#if WORDS_BIGENDIAN +#define SWAP_BE_WORD_TO_HOST(x) (x) +#else +#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x) +#endif + +#else + +typedef FLAC__uint64 bwword; +#define FLAC__BYTES_PER_WORD 8 /* sizeof bwword */ +#define FLAC__BITS_PER_WORD 64 +/* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ +#if WORDS_BIGENDIAN +#define SWAP_BE_WORD_TO_HOST(x) (x) +#else +#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_64(x) +#endif + +#endif + +/* + * The default capacity here doesn't matter too much. The buffer always grows + * to hold whatever is written to it. Usually the encoder will stop adding at + * a frame or metadata block, then write that out and clear the buffer for the + * next one. + */ +static const unsigned FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(bwword); /* size in words */ +/* When growing, increment 4K at a time */ +static const unsigned FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(bwword); /* size in words */ + +#define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD) +#define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits) + +struct FLAC__BitWriter { + bwword *buffer; + bwword accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */ + unsigned capacity; /* capacity of buffer in words */ + unsigned words; /* # of complete words in buffer */ + unsigned bits; /* # of used bits in accum */ +}; + +/* * WATCHOUT: The current implementation only grows the buffer. */ +#ifndef __SUNPRO_C +static +#endif +FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) +{ + unsigned new_capacity; + bwword *new_buffer; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + + /* calculate total words needed to store 'bits_to_add' additional bits */ + new_capacity = bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD); + + /* it's possible (due to pessimism in the growth estimation that + * leads to this call) that we don't actually need to grow + */ + if(bw->capacity >= new_capacity) + return true; + + /* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */ + if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT) + new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); + /* make sure we got everything right */ + FLAC__ASSERT(0 == (new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); + FLAC__ASSERT(new_capacity > bw->capacity); + FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); + + new_buffer = safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); + if(new_buffer == 0) + return false; + bw->buffer = new_buffer; + bw->capacity = new_capacity; + return true; +} + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +FLAC__BitWriter *FLAC__bitwriter_new(void) +{ + FLAC__BitWriter *bw = calloc(1, sizeof(FLAC__BitWriter)); + /* note that calloc() sets all members to 0 for us */ + return bw; +} + +void FLAC__bitwriter_delete(FLAC__BitWriter *bw) +{ + FLAC__ASSERT(0 != bw); + + FLAC__bitwriter_free(bw); + free(bw); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw) +{ + FLAC__ASSERT(0 != bw); + + bw->words = bw->bits = 0; + bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY; + bw->buffer = malloc(sizeof(bwword) * bw->capacity); + if(bw->buffer == 0) + return false; + + return true; +} + +void FLAC__bitwriter_free(FLAC__BitWriter *bw) +{ + FLAC__ASSERT(0 != bw); + + if(0 != bw->buffer) + free(bw->buffer); + bw->buffer = 0; + bw->capacity = 0; + bw->words = bw->bits = 0; +} + +void FLAC__bitwriter_clear(FLAC__BitWriter *bw) +{ + bw->words = bw->bits = 0; +} + +void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out) +{ + unsigned i, j; + if(bw == 0) { + fprintf(out, "bitwriter is NULL\n"); + } + else { + fprintf(out, "bitwriter: capacity=%u words=%u bits=%u total_bits=%u\n", bw->capacity, bw->words, bw->bits, FLAC__TOTAL_BITS(bw)); + + for(i = 0; i < bw->words; i++) { + fprintf(out, "%08X: ", i); + for(j = 0; j < FLAC__BITS_PER_WORD; j++) + fprintf(out, "%01u", bw->buffer[i] & ((bwword)1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); + fprintf(out, "\n"); + } + if(bw->bits > 0) { + fprintf(out, "%08X: ", i); + for(j = 0; j < bw->bits; j++) + fprintf(out, "%01u", bw->accum & ((bwword)1 << (bw->bits-j-1)) ? 1:0); + fprintf(out, "\n"); + } + } +} + +FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc) +{ + const FLAC__byte *buffer; + size_t bytes; + + FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */ + + if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes)) + return false; + + *crc = (FLAC__uint16)FLAC__crc16(buffer, bytes); + FLAC__bitwriter_release_buffer(bw); + return true; +} + +FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc) +{ + const FLAC__byte *buffer; + size_t bytes; + + FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */ + + if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes)) + return false; + + *crc = FLAC__crc8(buffer, bytes); + FLAC__bitwriter_release_buffer(bw); + return true; +} + +FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw) +{ + return ((bw->bits & 7) == 0); +} + +unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw) +{ + return FLAC__TOTAL_BITS(bw); +} + +FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes) +{ + FLAC__ASSERT((bw->bits & 7) == 0); + /* double protection */ + if(bw->bits & 7) + return false; + /* if we have bits in the accumulator we have to flush those to the buffer first */ + if(bw->bits) { + FLAC__ASSERT(bw->words <= bw->capacity); + if(bw->words == bw->capacity && !bitwriter_grow_(bw, FLAC__BITS_PER_WORD)) + return false; + /* append bits as complete word to buffer, but don't change bw->accum or bw->bits */ + bw->buffer[bw->words] = SWAP_BE_WORD_TO_HOST(bw->accum << (FLAC__BITS_PER_WORD-bw->bits)); + } + /* now we can just return what we have */ + *buffer = (FLAC__byte*)bw->buffer; + *bytes = (FLAC__BYTES_PER_WORD * bw->words) + (bw->bits >> 3); + return true; +} + +void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw) +{ + /* nothing to do. in the future, strict checking of a 'writer-is-in- + * get-mode' flag could be added everywhere and then cleared here + */ + (void)bw; +} + +inline FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits) +{ + unsigned n; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + + if(bits == 0) + return true; + /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ + if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits)) + return false; + /* first part gets to word alignment */ + if(bw->bits) { + n = flac_min(FLAC__BITS_PER_WORD - bw->bits, bits); + bw->accum <<= n; + bits -= n; + bw->bits += n; + if(bw->bits == FLAC__BITS_PER_WORD) { + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); + bw->bits = 0; + } + else + return true; + } + /* do whole words */ + while(bits >= FLAC__BITS_PER_WORD) { + bw->buffer[bw->words++] = 0; + bits -= FLAC__BITS_PER_WORD; + } + /* do any leftovers */ + if(bits > 0) { + bw->accum = 0; + bw->bits = bits; + } + return true; +} + +static inline FLAC__bool FLAC__bitwriter_write_raw_uint32_nocheck(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits) +{ + register unsigned left; + + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + + if(bw == 0 || bw->buffer == 0) + return false; + + if (bits > 32) + return false; + + if(bits == 0) + return true; + + FLAC__ASSERT((bits == 32) || (val>>bits == 0)); + + /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ + if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits)) + return false; + + left = FLAC__BITS_PER_WORD - bw->bits; + if(bits < left) { + bw->accum <<= bits; + bw->accum |= val; + bw->bits += bits; + } + else if(bw->bits) { /* WATCHOUT: if bw->bits == 0, left==FLAC__BITS_PER_WORD and bw->accum<<=left is a NOP instead of setting to 0 */ + bw->accum <<= left; + bw->accum |= val >> (bw->bits = bits - left); + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); + bw->accum = val; /* unused top bits can contain garbage */ + } + else { /* at this point bits == FLAC__BITS_PER_WORD == 32 and bw->bits == 0 */ + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST((bwword)val); + } + + return true; +} + +inline FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits) +{ + /* check that unused bits are unset */ + if((bits < 32) && (val>>bits != 0)) + return false; + + return FLAC__bitwriter_write_raw_uint32_nocheck(bw, val, bits); +} + +inline FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits) +{ + /* zero-out unused bits */ + if(bits < 32) + val &= (~(0xffffffff << bits)); + + return FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)val, bits); +} + +inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits) +{ + /* this could be a little faster but it's not used for much */ + if(bits > 32) { + return + FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(val>>32), bits-32) && + FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)val, 32); + } + else + return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); +} + +inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val) +{ + /* this doesn't need to be that fast as currently it is only used for vorbis comments */ + + if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, val & 0xff, 8)) + return false; + if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, (val>>8) & 0xff, 8)) + return false; + if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, (val>>16) & 0xff, 8)) + return false; + if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, val>>24, 8)) + return false; + + return true; +} + +inline FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals) +{ + unsigned i; + + /* this could be faster but currently we don't need it to be since it's only used for writing metadata */ + for(i = 0; i < nvals; i++) { + if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)(vals[i]), 8)) + return false; + } + + return true; +} + +FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val) +{ + if(val < 32) + return FLAC__bitwriter_write_raw_uint32_nocheck(bw, 1, ++val); + else + return + FLAC__bitwriter_write_zeroes(bw, val) && + FLAC__bitwriter_write_raw_uint32_nocheck(bw, 1, 1); +} + +unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter) +{ + FLAC__uint32 uval; + + FLAC__ASSERT(parameter < 32); + + /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */ + uval = val; + uval <<= 1; + uval ^= (val>>31); + + return 1 + parameter + (uval >> parameter); +} + +#if 0 /* UNUSED */ +unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter) +{ + unsigned bits, msbs, uval; + unsigned k; + + FLAC__ASSERT(parameter > 0); + + /* fold signed to unsigned */ + if(val < 0) + uval = (unsigned)(((-(++val)) << 1) + 1); + else + uval = (unsigned)(val << 1); + + k = FLAC__bitmath_ilog2(parameter); + if(parameter == 1u<<k) { + FLAC__ASSERT(k <= 30); + + msbs = uval >> k; + bits = 1 + k + msbs; + } + else { + unsigned q, r, d; + + d = (1 << (k+1)) - parameter; + q = uval / parameter; + r = uval - (q * parameter); + + bits = 1 + q + k; + if(r >= d) + bits++; + } + return bits; +} + +unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned uval, unsigned parameter) +{ + unsigned bits, msbs; + unsigned k; + + FLAC__ASSERT(parameter > 0); + + k = FLAC__bitmath_ilog2(parameter); + if(parameter == 1u<<k) { + FLAC__ASSERT(k <= 30); + + msbs = uval >> k; + bits = 1 + k + msbs; + } + else { + unsigned q, r, d; + + d = (1 << (k+1)) - parameter; + q = uval / parameter; + r = uval - (q * parameter); + + bits = 1 + q + k; + if(r >= d) + bits++; + } + return bits; +} +#endif /* UNUSED */ + +FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter) +{ + unsigned total_bits, interesting_bits, msbs; + FLAC__uint32 uval, pattern; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + FLAC__ASSERT(parameter < 32); + + /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */ + uval = val; + uval <<= 1; + uval ^= (val>>31); + + msbs = uval >> parameter; + interesting_bits = 1 + parameter; + total_bits = interesting_bits + msbs; + pattern = 1 << parameter; /* the unary end bit */ + pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */ + + if(total_bits <= 32) + return FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits); + else + return + FLAC__bitwriter_write_zeroes(bw, msbs) && /* write the unary MSBs */ + FLAC__bitwriter_write_raw_uint32(bw, pattern, interesting_bits); /* write the unary end bit and binary LSBs */ +} + +FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter) +{ + const FLAC__uint32 mask1 = (FLAC__uint32)0xffffffff << parameter; /* we val|=mask1 to set the stop bit above it... */ + const FLAC__uint32 mask2 = (FLAC__uint32)0xffffffff >> (31-parameter); /* ...then mask off the bits above the stop bit with val&=mask2 */ + FLAC__uint32 uval; + unsigned left; + const unsigned lsbits = 1 + parameter; + unsigned msbits, total_bits; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + FLAC__ASSERT(parameter < 31); + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + + while(nvals) { + /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */ + uval = *vals; + uval <<= 1; + uval ^= (*vals>>31); + + msbits = uval >> parameter; + total_bits = lsbits + msbits; + + if(bw->bits && bw->bits + total_bits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current bwword */ + /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free bwword to work in */ + bw->bits += total_bits; + uval |= mask1; /* set stop bit */ + uval &= mask2; /* mask off unused top bits */ + bw->accum <<= total_bits; + bw->accum |= uval; + } + else { + /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ + /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ + if(bw->capacity <= bw->words + bw->bits + msbits + 1 /* lsbits always fit in 1 bwword */ && !bitwriter_grow_(bw, total_bits)) + return false; + + if(msbits) { + /* first part gets to word alignment */ + if(bw->bits) { + left = FLAC__BITS_PER_WORD - bw->bits; + if(msbits < left) { + bw->accum <<= msbits; + bw->bits += msbits; + goto break1; + } + else { + bw->accum <<= left; + msbits -= left; + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); + bw->bits = 0; + } + } + /* do whole words */ + while(msbits >= FLAC__BITS_PER_WORD) { + bw->buffer[bw->words++] = 0; + msbits -= FLAC__BITS_PER_WORD; + } + /* do any leftovers */ + if(msbits > 0) { + bw->accum = 0; + bw->bits = msbits; + } + } +break1: + uval |= mask1; /* set stop bit */ + uval &= mask2; /* mask off unused top bits */ + + left = FLAC__BITS_PER_WORD - bw->bits; + if(lsbits < left) { + bw->accum <<= lsbits; + bw->accum |= uval; + bw->bits += lsbits; + } + else { + /* if bw->bits == 0, left==FLAC__BITS_PER_WORD which will always + * be > lsbits (because of previous assertions) so it would have + * triggered the (lsbits<left) case above. + */ + FLAC__ASSERT(bw->bits); + FLAC__ASSERT(left < FLAC__BITS_PER_WORD); + bw->accum <<= left; + bw->accum |= uval >> (bw->bits = lsbits - left); + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); + bw->accum = uval; /* unused top bits can contain garbage */ + } + } + vals++; + nvals--; + } + return true; +} + +#if 0 /* UNUSED */ +FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter) +{ + unsigned total_bits, msbs, uval; + unsigned k; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + FLAC__ASSERT(parameter > 0); + + /* fold signed to unsigned */ + if(val < 0) + uval = (unsigned)(((-(++val)) << 1) + 1); + else + uval = (unsigned)(val << 1); + + k = FLAC__bitmath_ilog2(parameter); + if(parameter == 1u<<k) { + unsigned pattern; + + FLAC__ASSERT(k <= 30); + + msbs = uval >> k; + total_bits = 1 + k + msbs; + pattern = 1 << k; /* the unary end bit */ + pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ + + if(total_bits <= 32) { + if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits)) + return false; + } + else { + /* write the unary MSBs */ + if(!FLAC__bitwriter_write_zeroes(bw, msbs)) + return false; + /* write the unary end bit and binary LSBs */ + if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1)) + return false; + } + } + else { + unsigned q, r, d; + + d = (1 << (k+1)) - parameter; + q = uval / parameter; + r = uval - (q * parameter); + /* write the unary MSBs */ + if(!FLAC__bitwriter_write_zeroes(bw, q)) + return false; + /* write the unary end bit */ + if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1)) + return false; + /* write the binary LSBs */ + if(r >= d) { + if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1)) + return false; + } + else { + if(!FLAC__bitwriter_write_raw_uint32(bw, r, k)) + return false; + } + } + return true; +} + +FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned uval, unsigned parameter) +{ + unsigned total_bits, msbs; + unsigned k; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + FLAC__ASSERT(parameter > 0); + + k = FLAC__bitmath_ilog2(parameter); + if(parameter == 1u<<k) { + unsigned pattern; + + FLAC__ASSERT(k <= 30); + + msbs = uval >> k; + total_bits = 1 + k + msbs; + pattern = 1 << k; /* the unary end bit */ + pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ + + if(total_bits <= 32) { + if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits)) + return false; + } + else { + /* write the unary MSBs */ + if(!FLAC__bitwriter_write_zeroes(bw, msbs)) + return false; + /* write the unary end bit and binary LSBs */ + if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1)) + return false; + } + } + else { + unsigned q, r, d; + + d = (1 << (k+1)) - parameter; + q = uval / parameter; + r = uval - (q * parameter); + /* write the unary MSBs */ + if(!FLAC__bitwriter_write_zeroes(bw, q)) + return false; + /* write the unary end bit */ + if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1)) + return false; + /* write the binary LSBs */ + if(r >= d) { + if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1)) + return false; + } + else { + if(!FLAC__bitwriter_write_raw_uint32(bw, r, k)) + return false; + } + } + return true; +} +#endif /* UNUSED */ + +FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val) +{ + FLAC__bool ok = 1; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + + if((val & 0x80000000) != 0) /* this version only handles 31 bits */ + return false; + + if(val < 0x80) { + return FLAC__bitwriter_write_raw_uint32_nocheck(bw, val, 8); + } + else if(val < 0x800) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xC0 | (val>>6), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); + } + else if(val < 0x10000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xE0 | (val>>12), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); + } + else if(val < 0x200000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF0 | (val>>18), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); + } + else if(val < 0x4000000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF8 | (val>>24), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>18)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); + } + else { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xFC | (val>>30), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>24)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>18)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); + } + + return ok; +} + +FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val) +{ + FLAC__bool ok = 1; + + FLAC__ASSERT(0 != bw); + FLAC__ASSERT(0 != bw->buffer); + + if((val & FLAC__U64L(0xFFFFFFF000000000)) != 0) /* this version only handles 36 bits */ + return false; + + if(val < 0x80) { + return FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)val, 8); + } + else if(val < 0x800) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xC0 | (FLAC__uint32)(val>>6), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); + } + else if(val < 0x10000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xE0 | (FLAC__uint32)(val>>12), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); + } + else if(val < 0x200000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF0 | (FLAC__uint32)(val>>18), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); + } + else if(val < 0x4000000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF8 | (FLAC__uint32)(val>>24), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); + } + else if(val < 0x80000000) { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xFC | (FLAC__uint32)(val>>30), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); + } + else { + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xFE, 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>30)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); + ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); + } + + return ok; +} + +FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw) +{ + /* 0-pad to byte boundary */ + if(bw->bits & 7u) + return FLAC__bitwriter_write_zeroes(bw, 8 - (bw->bits & 7u)); + else + return true; +} + +/* These functions are declared inline in this file but are also callable as + * externs from elsewhere. + * According to the C99 spec, section 6.7.4, simply providing a function + * prototype in a header file without 'inline' and making the function inline + * in this file should be sufficient. + * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To + * fix that we add extern declarations here. + */ +extern FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits); +extern FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits); +extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits); +extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits); +extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); +extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals); diff --git a/deps/flac-1.3.2/src/libFLAC/cpu.c b/deps/flac-1.3.2/src/libFLAC/cpu.c new file mode 100644 index 0000000..da76d87 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/cpu.c @@ -0,0 +1,293 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" +#include "share/compat.h" +#include <stdlib.h> +#include <string.h> + +#if defined(_MSC_VER) +# include <intrin.h> /* for __cpuid() and _xgetbv() */ +#endif + +#if defined __GNUC__ && defined HAVE_CPUID_H +# include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */ +#endif + +#ifdef DEBUG +#include <stdio.h> + +#define dfprintf fprintf +#else +/* This is bad practice, it should be a static void empty function */ +#define dfprintf(file, format, ...) +#endif + + +#if defined FLAC__CPU_IA32 +/* these are flags in EDX of CPUID AX=00000001 */ +static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; +#endif + +#if FLAC__HAS_X86INTRIN || FLAC__AVX_SUPPORTED +/* these are flags in ECX of CPUID AX=00000001 */ +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000; + +/* these are flags in ECX of CPUID AX=00000001 */ +static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000; +/* these are flags in EBX of CPUID AX=00000007 */ +static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020; +#endif + +#if defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64 +static uint32_t +cpu_xgetbv_x86(void) +{ +#if (defined _MSC_VER || defined __INTEL_COMPILER) && FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED + return (uint32_t)_xgetbv(0); +#elif defined __GNUC__ + uint32_t lo, hi; + asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); + return lo; +#else + return 0; +#endif +} +#endif + +static void +ia32_cpu_info (FLAC__CPUInfo *info) +{ +#if !defined FLAC__CPU_IA32 + (void) info; +#else + FLAC__bool ia32_osxsave = false; + FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; + +#if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) + info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */ +#if defined FLAC__HAS_NASM + if(!FLAC__cpu_have_cpuid_asm_ia32()) + return; +#endif + /* http://www.sandpile.org/x86/cpuid.htm */ + if (FLAC__HAS_X86INTRIN) { + FLAC__cpu_info_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->ia32.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */ + FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + } + else { + FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx); + } + + info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV ) ? true : false; + info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX ) ? true : false; + info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE ) ? true : false; + info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 ) ? true : false; + info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 ) ? true : false; + info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3) ? true : false; + info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41) ? true : false; + info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42) ? true : false; + + if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) { + ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false; + info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX ) ? true : false; + info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA ) ? true : false; + FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false; + } + + dfprintf(stderr, "CPU info (IA-32):\n"); + dfprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n'); + dfprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n'); + dfprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n'); + dfprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n'); + dfprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n'); + dfprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n'); + dfprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n'); + dfprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n'); + + if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) { + dfprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n'); + dfprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n'); + dfprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n'); + } + + /* + * now have to check for OS support of AVX instructions + */ + if (!FLAC__HAS_X86INTRIN || !info->ia32.avx || !ia32_osxsave || (cpu_xgetbv_x86() & 0x6) != 0x6) { + /* no OS AVX support */ + info->ia32.avx = false; + info->ia32.avx2 = false; + info->ia32.fma = false; + } + + if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) { + dfprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n'); + } +#else + info->use_asm = false; +#endif +#endif +} + +static void +x86_64_cpu_info (FLAC__CPUInfo *info) +{ +#if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN + FLAC__bool x86_osxsave = false; + FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; + + info->use_asm = true; + + /* http://www.sandpile.org/x86/cpuid.htm */ + FLAC__cpu_info_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */ + FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 ) ? true : false; + info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3) ? true : false; + info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41) ? true : false; + info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42) ? true : false; + + if (FLAC__AVX_SUPPORTED) { + x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false; + info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX ) ? true : false; + info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA ) ? true : false; + FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false; + } + + dfprintf(stderr, "CPU info (x86-64):\n"); + dfprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); + dfprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); + dfprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); + dfprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); + + if (FLAC__AVX_SUPPORTED) { + dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); + dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); + dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); + } + + /* + * now have to check for OS support of AVX instructions + */ + if (!info->x86.avx || !x86_osxsave || (cpu_xgetbv_x86() & 0x6) != 0x6) { + /* no OS AVX support */ + info->x86.avx = false; + info->x86.avx2 = false; + info->x86.fma = false; + } + + if (FLAC__AVX_SUPPORTED) { + dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); + } +#else + /* Silence compiler warnings. */ + (void) info; +#if defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64 + if (0) cpu_xgetbv_x86 (); +#endif +#endif +} + +void FLAC__cpu_info (FLAC__CPUInfo *info) +{ + memset(info, 0, sizeof(*info)); + +#ifdef FLAC__CPU_IA32 + info->type = FLAC__CPUINFO_TYPE_IA32; +#elif defined FLAC__CPU_X86_64 + info->type = FLAC__CPUINFO_TYPE_X86_64; +#else + info->type = FLAC__CPUINFO_TYPE_UNKNOWN; + info->use_asm = false; +#endif + + switch (info->type) { + case FLAC__CPUINFO_TYPE_IA32: + ia32_cpu_info (info); + break; + case FLAC__CPUINFO_TYPE_X86_64: + x86_64_cpu_info (info); + break; + default: + info->use_asm = false; + break; + } +} + +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN + +void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) +{ +#if defined _MSC_VER || defined __INTEL_COMPILER + int cpuinfo[4]; + int ext = level & 0x80000000; + __cpuid(cpuinfo, ext); + if((unsigned)cpuinfo[0] >= level) { +#if FLAC__AVX_SUPPORTED + __cpuidex(cpuinfo, ext, 0); /* for AVX2 detection */ +#else + __cpuid(cpuinfo, ext); /* some old compilers don't support __cpuidex */ +#endif + + *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; + + return; + } +#elif defined __GNUC__ && defined HAVE_CPUID_H + FLAC__uint32 ext = level & 0x80000000; + __cpuid(ext, *eax, *ebx, *ecx, *edx); + if (*eax >= level) { + __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); + + return; + } +#endif + *eax = *ebx = *ecx = *edx = 0; +} + +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ diff --git a/deps/flac-1.3.2/src/libFLAC/crc.c b/deps/flac-1.3.2/src/libFLAC/crc.c new file mode 100644 index 0000000..8123c3b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/crc.c @@ -0,0 +1,143 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/crc.h" + +/* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ + +FLAC__byte const FLAC__crc8_table[256] = { + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, + 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, + 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, + 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, + 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, + 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, + 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, + 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, + 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, + 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, + 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, + 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, + 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, + 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, + 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, + 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, + 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, + 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, + 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, + 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, + 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, + 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, + 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, + 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, + 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, + 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, + 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 +}; + +/* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ + +unsigned const FLAC__crc16_table[256] = { + 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, + 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, + 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, + 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, + 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, + 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, + 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, + 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, + 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, + 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, + 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, + 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, + 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, + 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, + 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, + 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, + 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 +}; + + +void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc) +{ + *crc = FLAC__crc8_table[*crc ^ data]; +} + +void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc) +{ + while(len--) + *crc = FLAC__crc8_table[*crc ^ *data++]; +} + +FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len) +{ + FLAC__uint8 crc = 0; + + while(len--) + crc = FLAC__crc8_table[crc ^ *data++]; + + return crc; +} + +unsigned FLAC__crc16(const FLAC__byte *data, unsigned len) +{ + unsigned crc = 0; + + while(len--) + crc = ((crc<<8) ^ FLAC__crc16_table[(crc>>8) ^ *data++]) & 0xffff; + + return crc; +} diff --git a/deps/flac-1.3.2/src/libFLAC/fixed.c b/deps/flac-1.3.2/src/libFLAC/fixed.c new file mode 100644 index 0000000..1e2d5b2 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/fixed.c @@ -0,0 +1,395 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <math.h> +#include <string.h> +#include "share/compat.h" +#include "private/bitmath.h" +#include "private/fixed.h" +#include "private/macros.h" +#include "FLAC/assert.h" + +#ifdef local_abs +#undef local_abs +#endif +#define local_abs(x) ((unsigned)((x)<0? -(x) : (x))) + +#ifdef FLAC__INTEGER_ONLY_LIBRARY +/* rbps stands for residual bits per sample + * + * (ln(2) * err) + * rbps = log (-----------) + * 2 ( n ) + */ +static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) +{ + FLAC__uint32 rbps; + unsigned bits; /* the number of bits required to represent a number */ + int fracbits; /* the number of bits of rbps that comprise the fractional part */ + + FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); + FLAC__ASSERT(err > 0); + FLAC__ASSERT(n > 0); + + FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); + if(err <= n) + return 0; + /* + * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. + * These allow us later to know we won't lose too much precision in the + * fixed-point division (err<<fracbits)/n. + */ + + fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1); + + err <<= fracbits; + err /= n; + /* err now holds err/n with fracbits fractional bits */ + + /* + * Whittle err down to 16 bits max. 16 significant bits is enough for + * our purposes. + */ + FLAC__ASSERT(err > 0); + bits = FLAC__bitmath_ilog2(err)+1; + if(bits > 16) { + err >>= (bits-16); + fracbits -= (bits-16); + } + rbps = (FLAC__uint32)err; + + /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ + rbps *= FLAC__FP_LN2; + fracbits += 16; + FLAC__ASSERT(fracbits >= 0); + + /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ + { + const int f = fracbits & 3; + if(f) { + rbps >>= f; + fracbits -= f; + } + } + + rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); + + if(rbps == 0) + return 0; + + /* + * The return value must have 16 fractional bits. Since the whole part + * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits + * must be >= -3, these assertion allows us to be able to shift rbps + * left if necessary to get 16 fracbits without losing any bits of the + * whole part of rbps. + * + * There is a slight chance due to accumulated error that the whole part + * will require 6 bits, so we use 6 in the assertion. Really though as + * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. + */ + FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); + FLAC__ASSERT(fracbits >= -3); + + /* now shift the decimal point into place */ + if(fracbits < 16) + return rbps << (16-fracbits); + else if(fracbits > 16) + return rbps >> (fracbits-16); + else + return rbps; +} + +static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) +{ + FLAC__uint32 rbps; + unsigned bits; /* the number of bits required to represent a number */ + int fracbits; /* the number of bits of rbps that comprise the fractional part */ + + FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); + FLAC__ASSERT(err > 0); + FLAC__ASSERT(n > 0); + + FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); + if(err <= n) + return 0; + /* + * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. + * These allow us later to know we won't lose too much precision in the + * fixed-point division (err<<fracbits)/n. + */ + + fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1); + + err <<= fracbits; + err /= n; + /* err now holds err/n with fracbits fractional bits */ + + /* + * Whittle err down to 16 bits max. 16 significant bits is enough for + * our purposes. + */ + FLAC__ASSERT(err > 0); + bits = FLAC__bitmath_ilog2_wide(err)+1; + if(bits > 16) { + err >>= (bits-16); + fracbits -= (bits-16); + } + rbps = (FLAC__uint32)err; + + /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ + rbps *= FLAC__FP_LN2; + fracbits += 16; + FLAC__ASSERT(fracbits >= 0); + + /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ + { + const int f = fracbits & 3; + if(f) { + rbps >>= f; + fracbits -= f; + } + } + + rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); + + if(rbps == 0) + return 0; + + /* + * The return value must have 16 fractional bits. Since the whole part + * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits + * must be >= -3, these assertion allows us to be able to shift rbps + * left if necessary to get 16 fracbits without losing any bits of the + * whole part of rbps. + * + * There is a slight chance due to accumulated error that the whole part + * will require 6 bits, so we use 6 in the assertion. Really though as + * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. + */ + FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); + FLAC__ASSERT(fracbits >= -3); + + /* now shift the decimal point into place */ + if(fracbits < 16) + return rbps << (16-fracbits); + else if(fracbits > 16) + return rbps >> (fracbits-16); + else + return rbps; +} +#endif + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#else +unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#endif +{ + FLAC__int32 last_error_0 = data[-1]; + FLAC__int32 last_error_1 = data[-1] - data[-2]; + FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); + FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); + FLAC__int32 error, save; + FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; + unsigned i, order; + + for(i = 0; i < data_len; i++) { + error = data[i] ; total_error_0 += local_abs(error); save = error; + error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; + error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; + error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; + error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; + } + + if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + order = 0; + else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + order = 1; + else if(total_error_2 < flac_min(total_error_3, total_error_4)) + order = 2; + else if(total_error_3 < total_error_4) + order = 3; + else + order = 4; + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); +#ifndef FLAC__INTEGER_ONLY_LIBRARY + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); +#else + residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; + residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; + residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; + residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; + residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; +#endif + + return order; +} + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#else +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#endif +{ + FLAC__int32 last_error_0 = data[-1]; + FLAC__int32 last_error_1 = data[-1] - data[-2]; + FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); + FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); + FLAC__int32 error, save; + /* total_error_* are 64-bits to avoid overflow when encoding + * erratic signals when the bits-per-sample and blocksize are + * large. + */ + FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; + unsigned i, order; + + for(i = 0; i < data_len; i++) { + error = data[i] ; total_error_0 += local_abs(error); save = error; + error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; + error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; + error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; + error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; + } + + if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + order = 0; + else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + order = 1; + else if(total_error_2 < flac_min(total_error_3, total_error_4)) + order = 2; + else if(total_error_3 < total_error_4) + order = 3; + else + order = 4; + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); +#ifndef FLAC__INTEGER_ONLY_LIBRARY + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); +#else + residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; + residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; + residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; + residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; + residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; +#endif + + return order; +} + +void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]) +{ + const int idata_len = (int)data_len; + int i; + + switch(order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(residual, data, sizeof(residual[0])*data_len); + break; + case 1: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - 2*data[i-1] + data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} + +void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]) +{ + int i, idata_len = (int)data_len; + + switch(order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(data, residual, sizeof(residual[0])*data_len); + break; + case 1: + for(i = 0; i < idata_len; i++) + data[i] = residual[i] + data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + data[i] = residual[i] + 2*data[i-1] - data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} diff --git a/deps/flac-1.3.2/src/libFLAC/fixed_intrin_sse2.c b/deps/flac-1.3.2/src/libFLAC/fixed_intrin_sse2.c new file mode 100644 index 0000000..6a9b4dd --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/fixed_intrin_sse2.c @@ -0,0 +1,255 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +#include "private/fixed.h" +#ifdef FLAC__SSE2_SUPPORTED + +#include <emmintrin.h> /* SSE2 */ +#include <math.h> +#include "private/macros.h" +#include "share/compat.h" +#include "FLAC/assert.h" + +#ifdef FLAC__CPU_IA32 +#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src) +#else +#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src) +#endif + +FLAC__SSE_TARGET("sse2") +unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) +{ + FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; + unsigned i, order; + + __m128i total_err0, total_err1, total_err2; + + { + FLAC__int32 itmp; + __m128i last_error; + + last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 + itmp = data[-2]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 + itmp -= data[-3]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 + itmp -= data[-3] - data[-4]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 + + total_err0 = total_err1 = _mm_setzero_si128(); + for(i = 0; i < data_len; i++) { + __m128i err0, err1, tmp; + err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 + err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 +#if 1 /* OPT_SSE */ + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#else + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#endif + tmp = _mm_slli_si128(err0, 12); // e0 0 0 0 + last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3 + last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3 + + tmp = _mm_srai_epi32(err0, 31); + err0 = _mm_xor_si128(err0, tmp); + err0 = _mm_sub_epi32(err0, tmp); + tmp = _mm_srai_epi32(err1, 31); + err1 = _mm_xor_si128(err1, tmp); + err1 = _mm_sub_epi32(err1, tmp); + + total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0 + total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4 + } + } + + total_error_0 = _mm_cvtsi128_si32(total_err0); + total_err2 = total_err1; // te1 te2 te3 te4 + total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2 + total_error_4 = _mm_cvtsi128_si32(total_err2); + total_error_2 = _mm_cvtsi128_si32(total_err1); + total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3 + total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1 + total_error_3 = _mm_cvtsi128_si32(total_err2); + total_error_1 = _mm_cvtsi128_si32(total_err1); + + /* prefer higher order */ + if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + order = 0; + else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + order = 1; + else if(total_error_2 < flac_min(total_error_3, total_error_4)) + order = 2; + else if(total_error_3 < total_error_4) + order = 3; + else + order = 4; + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); + + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + + return order; +} + +FLAC__SSE_TARGET("sse2") +unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) +{ + FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; + unsigned i, order; + + __m128i total_err0, total_err1, total_err3; + + { + FLAC__int32 itmp; + __m128i last_error, zero = _mm_setzero_si128(); + + last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 + itmp = data[-2]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 + itmp -= data[-3]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 + itmp -= data[-3] - data[-4]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 + + total_err0 = total_err1 = total_err3 = _mm_setzero_si128(); + for(i = 0; i < data_len; i++) { + __m128i err0, err1, tmp; + err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 + err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 +#if 1 /* OPT_SSE */ + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#else + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#endif + tmp = _mm_slli_si128(err0, 12); // e0 0 0 0 + last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3 + last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3 + + tmp = _mm_srai_epi32(err0, 31); + err0 = _mm_xor_si128(err0, tmp); + err0 = _mm_sub_epi32(err0, tmp); + tmp = _mm_srai_epi32(err1, 31); + err1 = _mm_xor_si128(err1, tmp); + err1 = _mm_sub_epi32(err1, tmp); + + total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0 + err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4| + err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2| + total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4 + total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2 + } + } + + m128i_to_i64(total_error_0, total_err0); + m128i_to_i64(total_error_4, total_err3); + m128i_to_i64(total_error_2, total_err1); + total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3 + total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1 + m128i_to_i64(total_error_3, total_err3); + m128i_to_i64(total_error_1, total_err1); + + /* prefer higher order */ + if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + order = 0; + else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + order = 1; + else if(total_error_2 < flac_min(total_error_3, total_error_4)) + order = 2; + else if(total_error_3 < total_error_4) + order = 3; + else + order = 4; + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); + + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + + return order; +} + +#endif /* FLAC__SSE2_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/fixed_intrin_ssse3.c b/deps/flac-1.3.2/src/libFLAC/fixed_intrin_ssse3.c new file mode 100644 index 0000000..f4d93e8 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/fixed_intrin_ssse3.c @@ -0,0 +1,243 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/fixed.h" +#ifdef FLAC__SSSE3_SUPPORTED + +#include <tmmintrin.h> /* SSSE3 */ +#include <math.h> +#include "private/macros.h" +#include "share/compat.h" +#include "FLAC/assert.h" + +#ifdef FLAC__CPU_IA32 +#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src) +#else +#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src) +#endif + +FLAC__SSE_TARGET("ssse3") +unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) +{ + FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; + unsigned i, order; + + __m128i total_err0, total_err1, total_err2; + + { + FLAC__int32 itmp; + __m128i last_error; + + last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 + itmp = data[-2]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 + itmp -= data[-3]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 + itmp -= data[-3] - data[-4]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 + + total_err0 = total_err1 = _mm_setzero_si128(); + for(i = 0; i < data_len; i++) { + __m128i err0, err1; + err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 + err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 +#if 1 /* OPT_SSE */ + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#else + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#endif + last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3 + + err0 = _mm_abs_epi32(err0); + err1 = _mm_abs_epi32(err1); + + total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0 + total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4 + } + } + + total_error_0 = _mm_cvtsi128_si32(total_err0); + total_err2 = total_err1; // te1 te2 te3 te4 + total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2 + total_error_4 = _mm_cvtsi128_si32(total_err2); + total_error_2 = _mm_cvtsi128_si32(total_err1); + total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3 + total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1 + total_error_3 = _mm_cvtsi128_si32(total_err2); + total_error_1 = _mm_cvtsi128_si32(total_err1); + + /* prefer higher order */ + if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + order = 0; + else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + order = 1; + else if(total_error_2 < flac_min(total_error_3, total_error_4)) + order = 2; + else if(total_error_3 < total_error_4) + order = 3; + else + order = 4; + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); + + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + + return order; +} + +FLAC__SSE_TARGET("ssse3") +unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) +{ + FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; + unsigned i, order; + + __m128i total_err0, total_err1, total_err3; + + { + FLAC__int32 itmp; + __m128i last_error, zero = _mm_setzero_si128(); + + last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 + itmp = data[-2]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 + itmp -= data[-3]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 + itmp -= data[-3] - data[-4]; + last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); + last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 + + total_err0 = total_err1 = total_err3 = _mm_setzero_si128(); + for(i = 0; i < data_len; i++) { + __m128i err0, err1; + err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 + err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 +#if 1 /* OPT_SSE */ + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 + err1 = _mm_sub_epi32(err1, last_error); + last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#else + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 + last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 + err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 +#endif + last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3 + + err0 = _mm_abs_epi32(err0); + err1 = _mm_abs_epi32(err1); // |e1| |e2| |e3| |e4| + + total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0 + err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4| + err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2| + total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4 + total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2 + } + } + + m128i_to_i64(total_error_0, total_err0); + m128i_to_i64(total_error_4, total_err3); + m128i_to_i64(total_error_2, total_err1); + total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3 + total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1 + m128i_to_i64(total_error_3, total_err3); + m128i_to_i64(total_error_1, total_err1); + + /* prefer higher order */ + if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + order = 0; + else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + order = 1; + else if(total_error_2 < flac_min(total_error_3, total_error_4)) + order = 2; + else if(total_error_3 < total_error_4) + order = 3; + else + order = 4; + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); + + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + + return order; +} + +#endif /* FLAC__SSSE3_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/flac.pc.in b/deps/flac-1.3.2/src/libFLAC/flac.pc.in new file mode 100644 index 0000000..56e8594 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/flac.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: FLAC +Description: Free Lossless Audio Codec Library +Version: @VERSION@ +Requires.private: @OGG_PACKAGE@ +Libs: -L${libdir} -lFLAC +Libs.private: -lm +Cflags: -I${includedir} diff --git a/deps/flac-1.3.2/src/libFLAC/float.c b/deps/flac-1.3.2/src/libFLAC/float.c new file mode 100644 index 0000000..25d1a78 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/float.c @@ -0,0 +1,302 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "FLAC/assert.h" +#include "share/compat.h" +#include "private/float.h" + +#ifdef FLAC__INTEGER_ONLY_LIBRARY + +const FLAC__fixedpoint FLAC__FP_ZERO = 0; +const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; +const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; +const FLAC__fixedpoint FLAC__FP_LN2 = 45426; +const FLAC__fixedpoint FLAC__FP_E = 178145; + +/* Lookup tables for Knuth's logarithm algorithm */ +#define LOG2_LOOKUP_PRECISION 16 +static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = { + { + /* + * 0 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00000001, + /* lg(4/3) = */ 0x00000000, + /* lg(8/7) = */ 0x00000000, + /* lg(16/15) = */ 0x00000000, + /* lg(32/31) = */ 0x00000000, + /* lg(64/63) = */ 0x00000000, + /* lg(128/127) = */ 0x00000000, + /* lg(256/255) = */ 0x00000000, + /* lg(512/511) = */ 0x00000000, + /* lg(1024/1023) = */ 0x00000000, + /* lg(2048/2047) = */ 0x00000000, + /* lg(4096/4095) = */ 0x00000000, + /* lg(8192/8191) = */ 0x00000000, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + * 4 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00000010, + /* lg(4/3) = */ 0x00000007, + /* lg(8/7) = */ 0x00000003, + /* lg(16/15) = */ 0x00000001, + /* lg(32/31) = */ 0x00000001, + /* lg(64/63) = */ 0x00000000, + /* lg(128/127) = */ 0x00000000, + /* lg(256/255) = */ 0x00000000, + /* lg(512/511) = */ 0x00000000, + /* lg(1024/1023) = */ 0x00000000, + /* lg(2048/2047) = */ 0x00000000, + /* lg(4096/4095) = */ 0x00000000, + /* lg(8192/8191) = */ 0x00000000, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + * 8 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00000100, + /* lg(4/3) = */ 0x0000006a, + /* lg(8/7) = */ 0x00000031, + /* lg(16/15) = */ 0x00000018, + /* lg(32/31) = */ 0x0000000c, + /* lg(64/63) = */ 0x00000006, + /* lg(128/127) = */ 0x00000003, + /* lg(256/255) = */ 0x00000001, + /* lg(512/511) = */ 0x00000001, + /* lg(1024/1023) = */ 0x00000000, + /* lg(2048/2047) = */ 0x00000000, + /* lg(4096/4095) = */ 0x00000000, + /* lg(8192/8191) = */ 0x00000000, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + * 12 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00001000, + /* lg(4/3) = */ 0x000006a4, + /* lg(8/7) = */ 0x00000315, + /* lg(16/15) = */ 0x0000017d, + /* lg(32/31) = */ 0x000000bc, + /* lg(64/63) = */ 0x0000005d, + /* lg(128/127) = */ 0x0000002e, + /* lg(256/255) = */ 0x00000017, + /* lg(512/511) = */ 0x0000000c, + /* lg(1024/1023) = */ 0x00000006, + /* lg(2048/2047) = */ 0x00000003, + /* lg(4096/4095) = */ 0x00000001, + /* lg(8192/8191) = */ 0x00000001, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + * 16 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00010000, + /* lg(4/3) = */ 0x00006a40, + /* lg(8/7) = */ 0x00003151, + /* lg(16/15) = */ 0x000017d6, + /* lg(32/31) = */ 0x00000bba, + /* lg(64/63) = */ 0x000005d1, + /* lg(128/127) = */ 0x000002e6, + /* lg(256/255) = */ 0x00000172, + /* lg(512/511) = */ 0x000000b9, + /* lg(1024/1023) = */ 0x0000005c, + /* lg(2048/2047) = */ 0x0000002e, + /* lg(4096/4095) = */ 0x00000017, + /* lg(8192/8191) = */ 0x0000000c, + /* lg(16384/16383) = */ 0x00000006, + /* lg(32768/32767) = */ 0x00000003 + }, + { + /* + * 20 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00100000, + /* lg(4/3) = */ 0x0006a3fe, + /* lg(8/7) = */ 0x00031513, + /* lg(16/15) = */ 0x00017d60, + /* lg(32/31) = */ 0x0000bb9d, + /* lg(64/63) = */ 0x00005d10, + /* lg(128/127) = */ 0x00002e59, + /* lg(256/255) = */ 0x00001721, + /* lg(512/511) = */ 0x00000b8e, + /* lg(1024/1023) = */ 0x000005c6, + /* lg(2048/2047) = */ 0x000002e3, + /* lg(4096/4095) = */ 0x00000171, + /* lg(8192/8191) = */ 0x000000b9, + /* lg(16384/16383) = */ 0x0000005c, + /* lg(32768/32767) = */ 0x0000002e + }, + { + /* + * 24 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x01000000, + /* lg(4/3) = */ 0x006a3fe6, + /* lg(8/7) = */ 0x00315130, + /* lg(16/15) = */ 0x0017d605, + /* lg(32/31) = */ 0x000bb9ca, + /* lg(64/63) = */ 0x0005d0fc, + /* lg(128/127) = */ 0x0002e58f, + /* lg(256/255) = */ 0x0001720e, + /* lg(512/511) = */ 0x0000b8d8, + /* lg(1024/1023) = */ 0x00005c61, + /* lg(2048/2047) = */ 0x00002e2d, + /* lg(4096/4095) = */ 0x00001716, + /* lg(8192/8191) = */ 0x00000b8b, + /* lg(16384/16383) = */ 0x000005c5, + /* lg(32768/32767) = */ 0x000002e3 + }, + { + /* + * 28 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x10000000, + /* lg(4/3) = */ 0x06a3fe5c, + /* lg(8/7) = */ 0x03151301, + /* lg(16/15) = */ 0x017d6049, + /* lg(32/31) = */ 0x00bb9ca6, + /* lg(64/63) = */ 0x005d0fba, + /* lg(128/127) = */ 0x002e58f7, + /* lg(256/255) = */ 0x001720da, + /* lg(512/511) = */ 0x000b8d87, + /* lg(1024/1023) = */ 0x0005c60b, + /* lg(2048/2047) = */ 0x0002e2d7, + /* lg(4096/4095) = */ 0x00017160, + /* lg(8192/8191) = */ 0x0000b8ad, + /* lg(16384/16383) = */ 0x00005c56, + /* lg(32768/32767) = */ 0x00002e2b + } +}; + +#if 0 +static const FLAC__uint64 log2_lookup_wide[] = { + { + /* + * 32 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ FLAC__U64L(0x100000000), + /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), + /* lg(8/7) = */ FLAC__U64L(0x31513015), + /* lg(16/15) = */ FLAC__U64L(0x17d60497), + /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), + /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), + /* lg(128/127) = */ FLAC__U64L(0x02e58f74), + /* lg(256/255) = */ FLAC__U64L(0x01720d9c), + /* lg(512/511) = */ FLAC__U64L(0x00b8d875), + /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), + /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), + /* lg(4096/4095) = */ FLAC__U64L(0x00171600), + /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), + /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), + /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) + }, + { + /* + * 48 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ FLAC__U64L(0x1000000000000), + /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), + /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), + /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), + /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), + /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), + /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), + /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), + /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), + /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), + /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), + /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), + /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), + /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), + /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) + } +}; +#endif + +FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision) +{ + const FLAC__uint32 ONE = (1u << fracbits); + const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; + + FLAC__ASSERT(fracbits < 32); + FLAC__ASSERT((fracbits & 0x3) == 0); + + if(x < ONE) + return 0; + + if(precision > LOG2_LOOKUP_PRECISION) + precision = LOG2_LOOKUP_PRECISION; + + /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ + { + FLAC__uint32 y = 0; + FLAC__uint32 z = x >> 1, k = 1; + while (x > ONE && k < precision) { + if (x - z >= ONE) { + x -= z; + z = x >> k; + y += table[k]; + } + else { + z >>= 1; + k++; + } + } + return y; + } +} + +#endif /* defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/format.c b/deps/flac-1.3.2/src/libFLAC/format.c new file mode 100644 index 0000000..214bd09 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/format.c @@ -0,0 +1,589 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> /* for qsort() */ +#include <string.h> /* for memset() */ +#include "FLAC/assert.h" +#include "FLAC/format.h" +#include "share/alloc.h" +#include "share/compat.h" +#include "private/format.h" +#include "private/macros.h" + +/* PACKAGE_VERSION should come from configure */ +FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION; + +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20170101"; + +FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; +FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; +FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */ + +FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff); + +FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */ + +FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */ +FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */ + +FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe; +FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */ +FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */ + +FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */ + +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */ +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */ +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */ +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */ +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */ + +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ +FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ + +FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = { + "PARTITIONED_RICE", + "PARTITIONED_RICE2" +}; + +FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */ +FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */ + +FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */ +FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */ +FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */ + +FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00; +FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02; +FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10; +FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40; + +FLAC_API const char * const FLAC__SubframeTypeString[] = { + "CONSTANT", + "VERBATIM", + "FIXED", + "LPC" +}; + +FLAC_API const char * const FLAC__ChannelAssignmentString[] = { + "INDEPENDENT", + "LEFT_SIDE", + "RIGHT_SIDE", + "MID_SIDE" +}; + +FLAC_API const char * const FLAC__FrameNumberTypeString[] = { + "FRAME_NUMBER_TYPE_FRAME_NUMBER", + "FRAME_NUMBER_TYPE_SAMPLE_NUMBER" +}; + +FLAC_API const char * const FLAC__MetadataTypeString[] = { + "STREAMINFO", + "PADDING", + "APPLICATION", + "SEEKTABLE", + "VORBIS_COMMENT", + "CUESHEET", + "PICTURE" +}; + +FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = { + "Other", + "32x32 pixels 'file icon' (PNG only)", + "Other file icon", + "Cover (front)", + "Cover (back)", + "Leaflet page", + "Media (e.g. label side of CD)", + "Lead artist/lead performer/soloist", + "Artist/performer", + "Conductor", + "Band/Orchestra", + "Composer", + "Lyricist/text writer", + "Recording Location", + "During recording", + "During performance", + "Movie/video screen capture", + "A bright coloured fish", + "Illustration", + "Band/artist logotype", + "Publisher/Studio logotype" +}; + +FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate) +{ + if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { + return false; + } + else + return true; +} + +FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate) +{ + if(blocksize > 16384) + return false; + else if(sample_rate <= 48000 && blocksize > 4608) + return false; + else + return true; +} + +FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate) +{ + if( + !FLAC__format_sample_rate_is_valid(sample_rate) || + ( + sample_rate >= (1u << 16) && + !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) + ) + ) { + return false; + } + else + return true; +} + +/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ +FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) +{ + unsigned i; + FLAC__uint64 prev_sample_number = 0; + FLAC__bool got_prev = false; + + FLAC__ASSERT(0 != seek_table); + + for(i = 0; i < seek_table->num_points; i++) { + if(got_prev) { + if( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].sample_number <= prev_sample_number + ) + return false; + } + prev_sample_number = seek_table->points[i].sample_number; + got_prev = true; + } + + return true; +} + +/* used as the sort predicate for qsort() */ +static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) +{ + /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ + if(l->sample_number == r->sample_number) + return 0; + else if(l->sample_number < r->sample_number) + return -1; + else + return 1; +} + +/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ +FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) +{ + unsigned i, j; + FLAC__bool first; + + FLAC__ASSERT(0 != seek_table); + + if (seek_table->num_points == 0) + return 0; + + /* sort the seekpoints */ + qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); + + /* uniquify the seekpoints */ + first = true; + for(i = j = 0; i < seek_table->num_points; i++) { + if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { + if(!first) { + if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) + continue; + } + } + first = false; + seek_table->points[j++] = seek_table->points[i]; + } + + for(i = j; i < seek_table->num_points; i++) { + seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + seek_table->points[i].stream_offset = 0; + seek_table->points[i].frame_samples = 0; + } + + return j; +} + +/* + * also disallows non-shortest-form encodings, c.f. + * http://www.unicode.org/versions/corrigendum1.html + * and a more clear explanation at the end of this section: + * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + */ +static unsigned utf8len_(const FLAC__byte *utf8) +{ + FLAC__ASSERT(0 != utf8); + if ((utf8[0] & 0x80) == 0) { + return 1; + } + else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { + if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */ + return 0; + return 2; + } + else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { + if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */ + return 0; + /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ + if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */ + return 0; + if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */ + return 0; + return 3; + } + else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { + if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */ + return 0; + return 4; + } + else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { + if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */ + return 0; + return 5; + } + else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) { + if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */ + return 0; + return 6; + } + else { + return 0; + } +} + +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) +{ + char c; + for(c = *name; c; c = *(++name)) + if(c < 0x20 || c == 0x3d || c > 0x7d) + return false; + return true; +} + +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length) +{ + if(length == (unsigned)(-1)) { + while(*value) { + unsigned n = utf8len_(value); + if(n == 0) + return false; + value += n; + } + } + else { + const FLAC__byte *end = value + length; + while(value < end) { + unsigned n = utf8len_(value); + if(n == 0) + return false; + value += n; + } + if(value != end) + return false; + } + return true; +} + +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length) +{ + const FLAC__byte *s, *end; + + for(s = entry, end = s + length; s < end && *s != '='; s++) { + if(*s < 0x20 || *s > 0x7D) + return false; + } + if(s == end) + return false; + + s++; /* skip '=' */ + + while(s < end) { + unsigned n = utf8len_(s); + if(n == 0) + return false; + s += n; + } + if(s != end) + return false; + + return true; +} + +/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ +FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) +{ + unsigned i, j; + + if(check_cd_da_subset) { + if(cue_sheet->lead_in < 2 * 44100) { + if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; + return false; + } + if(cue_sheet->lead_in % 588 != 0) { + if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; + return false; + } + } + + if(cue_sheet->num_tracks == 0) { + if(violation) *violation = "cue sheet must have at least one track (the lead-out)"; + return false; + } + + if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) { + if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; + return false; + } + + for(i = 0; i < cue_sheet->num_tracks; i++) { + if(cue_sheet->tracks[i].number == 0) { + if(violation) *violation = "cue sheet may not have a track number 0"; + return false; + } + + if(check_cd_da_subset) { + if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { + if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170"; + return false; + } + } + + if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { + if(violation) { + if(i == cue_sheet->num_tracks-1) /* the lead-out track... */ + *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples"; + else + *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; + } + return false; + } + + if(i < cue_sheet->num_tracks - 1) { + if(cue_sheet->tracks[i].num_indices == 0) { + if(violation) *violation = "cue sheet track must have at least one index point"; + return false; + } + + if(cue_sheet->tracks[i].indices[0].number > 1) { + if(violation) *violation = "cue sheet track's first index number must be 0 or 1"; + return false; + } + } + + for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) { + if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { + if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; + return false; + } + + if(j > 0) { + if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) { + if(violation) *violation = "cue sheet track index numbers must increase by 1"; + return false; + } + } + } + } + + return true; +} + +/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ +FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) +{ + char *p; + FLAC__byte *b; + + for(p = picture->mime_type; *p; p++) { + if(*p < 0x20 || *p > 0x7e) { + if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; + return false; + } + } + + for(b = picture->description; *b; ) { + unsigned n = utf8len_(b); + if(n == 0) { + if(violation) *violation = "description string must be valid UTF-8"; + return false; + } + b += n; + } + + return true; +} + +/* + * These routines are private to libFLAC + */ +unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order) +{ + return + FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( + FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), + blocksize, + predictor_order + ); +} + +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize) +{ + unsigned max_rice_partition_order = 0; + while(!(blocksize & 1)) { + max_rice_partition_order++; + blocksize >>= 1; + } + return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); +} + +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) +{ + unsigned max_rice_partition_order = limit; + + while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) + max_rice_partition_order--; + + FLAC__ASSERT( + (max_rice_partition_order == 0 && blocksize >= predictor_order) || + (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) + ); + + return max_rice_partition_order; +} + +void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) +{ + FLAC__ASSERT(0 != object); + + object->parameters = 0; + object->raw_bits = 0; + object->capacity_by_order = 0; +} + +void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) +{ + FLAC__ASSERT(0 != object); + + if(0 != object->parameters) + free(object->parameters); + if(0 != object->raw_bits) + free(object->raw_bits); + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); +} + +FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order) +{ + FLAC__ASSERT(0 != object); + + FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); + + if(object->capacity_by_order < max_partition_order) { + if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) + return false; + if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) + return false; + memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order)); + object->capacity_by_order = max_partition_order; + } + + return true; +} diff --git a/deps/flac-1.3.2/src/libFLAC/ia32/Makefile.am b/deps/flac-1.3.2/src/libFLAC/ia32/Makefile.am new file mode 100644 index 0000000..5b4880b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ia32/Makefile.am @@ -0,0 +1,44 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +SUFFIXES = .nasm .lo + +STRIP_NON_ASM = sh $(top_srcdir)/strip_non_asm_libtool_args.sh +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +.nasm.lo: + $(LIBTOOL) --tag=CC --mode=compile $(STRIP_NON_ASM) $(NASM) -f $(OBJ_FORMAT) -d OBJ_FORMAT_$(OBJ_FORMAT) -i$(srcdir)/ $< -o $@ + +noinst_LTLIBRARIES = libFLAC-asm.la +libFLAC_asm_la_SOURCES = \ + cpu_asm.nasm \ + fixed_asm.nasm \ + lpc_asm.nasm \ + nasm.h diff --git a/deps/flac-1.3.2/src/libFLAC/ia32/Makefile.in b/deps/flac-1.3.2/src/libFLAC/ia32/Makefile.in new file mode 100644 index 0000000..38e1967 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ia32/Makefile.in @@ -0,0 +1,640 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libFLAC/ia32 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libFLAC_asm_la_LIBADD = +am_libFLAC_asm_la_OBJECTS = cpu_asm.lo fixed_asm.lo lpc_asm.lo +libFLAC_asm_la_OBJECTS = $(am_libFLAC_asm_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libFLAC_asm_la_SOURCES) +DIST_SOURCES = $(libFLAC_asm_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUFFIXES = .nasm .lo +STRIP_NON_ASM = sh $(top_srcdir)/strip_non_asm_libtool_args.sh +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +noinst_LTLIBRARIES = libFLAC-asm.la +libFLAC_asm_la_SOURCES = \ + cpu_asm.nasm \ + fixed_asm.nasm \ + lpc_asm.nasm \ + nasm.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .nasm .lo +$(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/libFLAC/ia32/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libFLAC/ia32/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)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libFLAC-asm.la: $(libFLAC_asm_la_OBJECTS) $(libFLAC_asm_la_DEPENDENCIES) $(EXTRA_libFLAC_asm_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libFLAC_asm_la_OBJECTS) $(libFLAC_asm_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 + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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) +installdirs: +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 -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-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f 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: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + +.nasm.lo: + $(LIBTOOL) --tag=CC --mode=compile $(STRIP_NON_ASM) $(NASM) -f $(OBJ_FORMAT) -d OBJ_FORMAT_$(OBJ_FORMAT) -i$(srcdir)/ $< -o $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/src/libFLAC/ia32/cpu_asm.nasm b/deps/flac-1.3.2/src/libFLAC/ia32/cpu_asm.nasm new file mode 100644 index 0000000..31baa0a --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ia32/cpu_asm.nasm @@ -0,0 +1,99 @@ +; vim:filetype=nasm ts=8 + +; libFLAC - Free Lossless Audio Codec library +; Copyright (C) 2001-2009 Josh Coalson +; Copyright (C) 2011-2016 Xiph.Org Foundation +; +; 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 the Xiph.org Foundation 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 FOUNDATION 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. + +%include "nasm.h" + + data_section + +cglobal FLAC__cpu_have_cpuid_asm_ia32 +cglobal FLAC__cpu_info_asm_ia32 + + code_section + +; ********************************************************************** +; +; FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32() +; + +cident FLAC__cpu_have_cpuid_asm_ia32 + pushfd + pop eax + mov edx, eax + xor eax, 0x00200000 + push eax + popfd + pushfd + pop eax + xor eax, edx + and eax, 0x00200000 + shr eax, 0x15 + push edx + popfd + ret + +; ********************************************************************** +; +; void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx) +; + +cident FLAC__cpu_info_asm_ia32 + ;[esp + 8] == flags_edx + ;[esp + 12] == flags_ecx + + push ebx + call FLAC__cpu_have_cpuid_asm_ia32 + test eax, eax + jz .no_cpuid + mov eax, 0 + cpuid + cmp eax, 1 + jb .no_cpuid + xor ecx, ecx + mov eax, 1 + cpuid + mov ebx, [esp + 8] + mov [ebx], edx + mov ebx, [esp + 12] + mov [ebx], ecx + jmp .end +.no_cpuid: + xor eax, eax + mov ebx, [esp + 8] + mov [ebx], eax + mov ebx, [esp + 12] + mov [ebx], eax +.end: + pop ebx + ret + +; end diff --git a/deps/flac-1.3.2/src/libFLAC/ia32/fixed_asm.nasm b/deps/flac-1.3.2/src/libFLAC/ia32/fixed_asm.nasm new file mode 100644 index 0000000..8477724 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ia32/fixed_asm.nasm @@ -0,0 +1,309 @@ +; vim:filetype=nasm ts=8 + +; libFLAC - Free Lossless Audio Codec library +; Copyright (C) 2001-2009 Josh Coalson +; Copyright (C) 2011-2016 Xiph.Org Foundation +; +; 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 the Xiph.org Foundation 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 FOUNDATION 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. + +%include "nasm.h" + + data_section + +cglobal FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov + + code_section + +; ********************************************************************** +; +; unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 *data, unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +; { +; FLAC__int32 last_error_0 = data[-1]; +; FLAC__int32 last_error_1 = data[-1] - data[-2]; +; FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); +; FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); +; FLAC__int32 error, save; +; FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; +; unsigned i, order; +; +; for(i = 0; i < data_len; i++) { +; error = data[i] ; total_error_0 += local_abs(error); save = error; +; error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; +; error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; +; error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; +; error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; +; } +; +; if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4)) +; order = 0; +; else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4)) +; order = 1; +; else if(total_error_2 < min(total_error_3, total_error_4)) +; order = 2; +; else if(total_error_3 < total_error_4) +; order = 3; +; else +; order = 4; +; +; residual_bits_per_sample[0] = (float)((data_len > 0 && total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); +; residual_bits_per_sample[1] = (float)((data_len > 0 && total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); +; residual_bits_per_sample[2] = (float)((data_len > 0 && total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); +; residual_bits_per_sample[3] = (float)((data_len > 0 && total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); +; residual_bits_per_sample[4] = (float)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); +; +; return order; +; } + ALIGN 16 +cident FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov + + ; esp + 36 == data[] + ; esp + 40 == data_len + ; esp + 44 == residual_bits_per_sample[] + + push ebp + push ebx + push esi + push edi + sub esp, byte 16 + ; qword [esp] == temp space for loading FLAC__uint64s to FPU regs + + ; ebx == &data[i] + ; ecx == loop counter (i) + ; ebp == order + ; mm0 == total_error_1:total_error_0 + ; mm1 == total_error_2:total_error_3 + ; mm2 == :total_error_4 + ; mm3 == last_error_1:last_error_0 + ; mm4 == last_error_2:last_error_3 + + mov ecx, [esp + 40] ; ecx = data_len + test ecx, ecx + jz near .data_len_is_0 + + mov ebx, [esp + 36] ; ebx = data[] + movd mm3, [ebx - 4] ; mm3 = 0:last_error_0 + movd mm2, [ebx - 8] ; mm2 = 0:data[-2] + movd mm1, [ebx - 12] ; mm1 = 0:data[-3] + movd mm0, [ebx - 16] ; mm0 = 0:data[-4] + movq mm5, mm3 ; mm5 = 0:last_error_0 + psubd mm5, mm2 ; mm5 = 0:last_error_1 + punpckldq mm3, mm5 ; mm3 = last_error_1:last_error_0 + psubd mm2, mm1 ; mm2 = 0:data[-2] - data[-3] + psubd mm5, mm2 ; mm5 = 0:last_error_2 + movq mm4, mm5 ; mm4 = 0:last_error_2 + psubd mm4, mm2 ; mm4 = 0:last_error_2 - (data[-2] - data[-3]) + paddd mm4, mm1 ; mm4 = 0:last_error_2 - (data[-2] - 2 * data[-3]) + psubd mm4, mm0 ; mm4 = 0:last_error_3 + punpckldq mm4, mm5 ; mm4 = last_error_2:last_error_3 + pxor mm0, mm0 ; mm0 = total_error_1:total_error_0 + pxor mm1, mm1 ; mm1 = total_error_2:total_error_3 + pxor mm2, mm2 ; mm2 = 0:total_error_4 + + ALIGN 16 +.loop: + movd mm7, [ebx] ; mm7 = 0:error_0 + add ebx, byte 4 + movq mm6, mm7 ; mm6 = 0:error_0 + psubd mm7, mm3 ; mm7 = :error_1 + punpckldq mm6, mm7 ; mm6 = error_1:error_0 + movq mm5, mm6 ; mm5 = error_1:error_0 + movq mm7, mm6 ; mm7 = error_1:error_0 + psubd mm5, mm3 ; mm5 = error_2: + movq mm3, mm6 ; mm3 = error_1:error_0 + psrad mm6, 31 + pxor mm7, mm6 + psubd mm7, mm6 ; mm7 = abs(error_1):abs(error_0) + paddd mm0, mm7 ; mm0 = total_error_1:total_error_0 + movq mm6, mm5 ; mm6 = error_2: + psubd mm5, mm4 ; mm5 = error_3: + punpckhdq mm5, mm6 ; mm5 = error_2:error_3 + movq mm7, mm5 ; mm7 = error_2:error_3 + movq mm6, mm5 ; mm6 = error_2:error_3 + psubd mm5, mm4 ; mm5 = :error_4 + movq mm4, mm6 ; mm4 = error_2:error_3 + psrad mm6, 31 + pxor mm7, mm6 + psubd mm7, mm6 ; mm7 = abs(error_2):abs(error_3) + paddd mm1, mm7 ; mm1 = total_error_2:total_error_3 + movq mm6, mm5 ; mm6 = :error_4 + psrad mm5, 31 + pxor mm6, mm5 + psubd mm6, mm5 ; mm6 = :abs(error_4) + paddd mm2, mm6 ; mm2 = :total_error_4 + + dec ecx + jnz short .loop + +; if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4)) +; order = 0; +; else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4)) +; order = 1; +; else if(total_error_2 < min(total_error_3, total_error_4)) +; order = 2; +; else if(total_error_3 < total_error_4) +; order = 3; +; else +; order = 4; + movq mm3, mm0 ; mm3 = total_error_1:total_error_0 + movd edi, mm2 ; edi = total_error_4 + movd esi, mm1 ; esi = total_error_3 + movd eax, mm0 ; eax = total_error_0 + punpckhdq mm1, mm1 ; mm1 = total_error_2:total_error_2 + punpckhdq mm3, mm3 ; mm3 = total_error_1:total_error_1 + movd edx, mm1 ; edx = total_error_2 + movd ecx, mm3 ; ecx = total_error_1 + + xor ebx, ebx + xor ebp, ebp + inc ebx + cmp ecx, eax + cmovb eax, ecx ; eax = min(total_error_0, total_error_1) + cmovbe ebp, ebx + inc ebx + cmp edx, eax + cmovb eax, edx ; eax = min(total_error_0, total_error_1, total_error_2) + cmovbe ebp, ebx + inc ebx + cmp esi, eax + cmovb eax, esi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3) + cmovbe ebp, ebx + inc ebx + cmp edi, eax + cmovb eax, edi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3, total_error_4) + cmovbe ebp, ebx + movd ebx, mm0 ; ebx = total_error_0 + emms + + ; residual_bits_per_sample[0] = (float)((data_len > 0 && total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + ; residual_bits_per_sample[1] = (float)((data_len > 0 && total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + ; residual_bits_per_sample[2] = (float)((data_len > 0 && total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + ; residual_bits_per_sample[3] = (float)((data_len > 0 && total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + ; residual_bits_per_sample[4] = (float)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + xor eax, eax + fild dword [esp + 40] ; ST = data_len (NOTE: assumes data_len is <2gigs) +.rbps_0: + test ebx, ebx + jz .total_error_0_is_0 + fld1 ; ST = 1.0 data_len + mov [esp], ebx + mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_0 + mov ebx, [esp + 44] + fild qword [esp] ; ST = total_error_0 1.0 data_len + fdiv st2 ; ST = total_error_0/data_len 1.0 data_len + fldln2 ; ST = ln2 total_error_0/data_len 1.0 data_len + fmulp st1 ; ST = ln2*total_error_0/data_len 1.0 data_len + fyl2x ; ST = log2(ln2*total_error_0/data_len) data_len + fstp dword [ebx] ; residual_bits_per_sample[0] = log2(ln2*total_error_0/data_len) ST = data_len + jmp short .rbps_1 +.total_error_0_is_0: + mov ebx, [esp + 44] + mov [ebx], eax ; residual_bits_per_sample[0] = 0.0 +.rbps_1: + test ecx, ecx + jz .total_error_1_is_0 + fld1 ; ST = 1.0 data_len + mov [esp], ecx + mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_1 + fild qword [esp] ; ST = total_error_1 1.0 data_len + fdiv st2 ; ST = total_error_1/data_len 1.0 data_len + fldln2 ; ST = ln2 total_error_1/data_len 1.0 data_len + fmulp st1 ; ST = ln2*total_error_1/data_len 1.0 data_len + fyl2x ; ST = log2(ln2*total_error_1/data_len) data_len + fstp dword [ebx + 4] ; residual_bits_per_sample[1] = log2(ln2*total_error_1/data_len) ST = data_len + jmp short .rbps_2 +.total_error_1_is_0: + mov [ebx + 4], eax ; residual_bits_per_sample[1] = 0.0 +.rbps_2: + test edx, edx + jz .total_error_2_is_0 + fld1 ; ST = 1.0 data_len + mov [esp], edx + mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_2 + fild qword [esp] ; ST = total_error_2 1.0 data_len + fdiv st2 ; ST = total_error_2/data_len 1.0 data_len + fldln2 ; ST = ln2 total_error_2/data_len 1.0 data_len + fmulp st1 ; ST = ln2*total_error_2/data_len 1.0 data_len + fyl2x ; ST = log2(ln2*total_error_2/data_len) data_len + fstp dword [ebx + 8] ; residual_bits_per_sample[2] = log2(ln2*total_error_2/data_len) ST = data_len + jmp short .rbps_3 +.total_error_2_is_0: + mov [ebx + 8], eax ; residual_bits_per_sample[2] = 0.0 +.rbps_3: + test esi, esi + jz .total_error_3_is_0 + fld1 ; ST = 1.0 data_len + mov [esp], esi + mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_3 + fild qword [esp] ; ST = total_error_3 1.0 data_len + fdiv st2 ; ST = total_error_3/data_len 1.0 data_len + fldln2 ; ST = ln2 total_error_3/data_len 1.0 data_len + fmulp st1 ; ST = ln2*total_error_3/data_len 1.0 data_len + fyl2x ; ST = log2(ln2*total_error_3/data_len) data_len + fstp dword [ebx + 12] ; residual_bits_per_sample[3] = log2(ln2*total_error_3/data_len) ST = data_len + jmp short .rbps_4 +.total_error_3_is_0: + mov [ebx + 12], eax ; residual_bits_per_sample[3] = 0.0 +.rbps_4: + test edi, edi + jz .total_error_4_is_0 + fld1 ; ST = 1.0 data_len + mov [esp], edi + mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_4 + fild qword [esp] ; ST = total_error_4 1.0 data_len + fdiv st2 ; ST = total_error_4/data_len 1.0 data_len + fldln2 ; ST = ln2 total_error_4/data_len 1.0 data_len + fmulp st1 ; ST = ln2*total_error_4/data_len 1.0 data_len + fyl2x ; ST = log2(ln2*total_error_4/data_len) data_len + fstp dword [ebx + 16] ; residual_bits_per_sample[4] = log2(ln2*total_error_4/data_len) ST = data_len + jmp short .rbps_end +.total_error_4_is_0: + mov [ebx + 16], eax ; residual_bits_per_sample[4] = 0.0 +.rbps_end: + fstp st0 ; ST = [empty] + jmp short .end +.data_len_is_0: + ; data_len == 0, so residual_bits_per_sample[*] = 0.0 + xor ebp, ebp + mov edi, [esp + 44] + mov [edi], ebp + mov [edi + 4], ebp + mov [edi + 8], ebp + mov [edi + 12], ebp + mov [edi + 16], ebp + add ebp, byte 4 ; order = 4 + +.end: + mov eax, ebp ; return order + add esp, byte 16 + pop edi + pop esi + pop ebx + pop ebp + ret + +; end diff --git a/deps/flac-1.3.2/src/libFLAC/ia32/lpc_asm.nasm b/deps/flac-1.3.2/src/libFLAC/ia32/lpc_asm.nasm new file mode 100644 index 0000000..8539d9b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ia32/lpc_asm.nasm @@ -0,0 +1,2049 @@ +; vim:filetype=nasm ts=8 + +; libFLAC - Free Lossless Audio Codec library +; Copyright (C) 2001-2009 Josh Coalson +; Copyright (C) 2011-2016 Xiph.Org Foundation +; +; 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 the Xiph.org Foundation 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 FOUNDATION 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. + +%include "nasm.h" + + data_section + +cglobal FLAC__lpc_compute_autocorrelation_asm_ia32 +cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old +cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old +cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old +cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old +cglobal FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32 +cglobal FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx +cglobal FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32 +cglobal FLAC__lpc_restore_signal_asm_ia32 +cglobal FLAC__lpc_restore_signal_asm_ia32_mmx +cglobal FLAC__lpc_restore_signal_wide_asm_ia32 + + code_section + +; ********************************************************************** +; +; void FLAC__lpc_compute_autocorrelation_asm(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +; { +; FLAC__real d; +; unsigned sample, coeff; +; const unsigned limit = data_len - lag; +; +; FLAC__ASSERT(lag > 0); +; FLAC__ASSERT(lag <= data_len); +; +; for(coeff = 0; coeff < lag; coeff++) +; autoc[coeff] = 0.0; +; for(sample = 0; sample <= limit; sample++) { +; d = data[sample]; +; for(coeff = 0; coeff < lag; coeff++) +; autoc[coeff] += d * data[sample+coeff]; +; } +; for(; sample < data_len; sample++) { +; d = data[sample]; +; for(coeff = 0; coeff < data_len - sample; coeff++) +; autoc[coeff] += d * data[sample+coeff]; +; } +; } +; + ALIGN 16 +cident FLAC__lpc_compute_autocorrelation_asm_ia32 + ;[esp + 28] == autoc[] + ;[esp + 24] == lag + ;[esp + 20] == data_len + ;[esp + 16] == data[] + + ;ASSERT(lag > 0) + ;ASSERT(lag <= 33) + ;ASSERT(lag <= data_len) + +.begin: + push esi + push edi + push ebx + + ; for(coeff = 0; coeff < lag; coeff++) + ; autoc[coeff] = 0.0; + mov edi, [esp + 28] ; edi == autoc + mov ecx, [esp + 24] ; ecx = # of dwords (=lag) of 0 to write + xor eax, eax + rep stosd + + ; const unsigned limit = data_len - lag; + mov eax, [esp + 24] ; eax == lag + mov ecx, [esp + 20] + sub ecx, eax ; ecx == limit + + mov edi, [esp + 28] ; edi == autoc + mov esi, [esp + 16] ; esi == data + inc ecx ; we are looping <= limit so we add one to the counter + + ; for(sample = 0; sample <= limit; sample++) { + ; d = data[sample]; + ; for(coeff = 0; coeff < lag; coeff++) + ; autoc[coeff] += d * data[sample+coeff]; + ; } + fld dword [esi] ; ST = d <- data[sample] + ; each iteration is 11 bytes so we need (-eax)*11, so we do (-12*eax + eax) + lea edx, [eax + eax*2] + neg edx + lea edx, [eax + edx*4 + .jumper1_0 - .get_eip1] + call .mov_eip_to_ebx +.get_eip1: + add edx, ebx + inc edx ; compensate for the shorter opcode on the last iteration + inc edx ; compensate for the shorter opcode on the last iteration + inc edx ; compensate for the shorter opcode on the last iteration + cmp eax, 33 + jne .loop1_start + sub edx, byte 9 ; compensate for the longer opcodes on the first iteration +.loop1_start: + jmp edx + +.mov_eip_to_ebx: + mov ebx, [esp] + ret + + fld st0 ; ST = d d + fmul dword [esi + (32*4)] ; ST = d*data[sample+32] d WATCHOUT: not a byte displacement here! + fadd dword [edi + (32*4)] ; ST = autoc[32]+d*data[sample+32] d WATCHOUT: not a byte displacement here! + fstp dword [edi + (32*4)] ; autoc[32]+=d*data[sample+32] ST = d WATCHOUT: not a byte displacement here! + fld st0 ; ST = d d + fmul dword [esi + (31*4)] ; ST = d*data[sample+31] d + fadd dword [edi + (31*4)] ; ST = autoc[31]+d*data[sample+31] d + fstp dword [edi + (31*4)] ; autoc[31]+=d*data[sample+31] ST = d + fld st0 ; ST = d d + fmul dword [esi + (30*4)] ; ST = d*data[sample+30] d + fadd dword [edi + (30*4)] ; ST = autoc[30]+d*data[sample+30] d + fstp dword [edi + (30*4)] ; autoc[30]+=d*data[sample+30] ST = d + fld st0 ; ST = d d + fmul dword [esi + (29*4)] ; ST = d*data[sample+29] d + fadd dword [edi + (29*4)] ; ST = autoc[29]+d*data[sample+29] d + fstp dword [edi + (29*4)] ; autoc[29]+=d*data[sample+29] ST = d + fld st0 ; ST = d d + fmul dword [esi + (28*4)] ; ST = d*data[sample+28] d + fadd dword [edi + (28*4)] ; ST = autoc[28]+d*data[sample+28] d + fstp dword [edi + (28*4)] ; autoc[28]+=d*data[sample+28] ST = d + fld st0 ; ST = d d + fmul dword [esi + (27*4)] ; ST = d*data[sample+27] d + fadd dword [edi + (27*4)] ; ST = autoc[27]+d*data[sample+27] d + fstp dword [edi + (27*4)] ; autoc[27]+=d*data[sample+27] ST = d + fld st0 ; ST = d d + fmul dword [esi + (26*4)] ; ST = d*data[sample+26] d + fadd dword [edi + (26*4)] ; ST = autoc[26]+d*data[sample+26] d + fstp dword [edi + (26*4)] ; autoc[26]+=d*data[sample+26] ST = d + fld st0 ; ST = d d + fmul dword [esi + (25*4)] ; ST = d*data[sample+25] d + fadd dword [edi + (25*4)] ; ST = autoc[25]+d*data[sample+25] d + fstp dword [edi + (25*4)] ; autoc[25]+=d*data[sample+25] ST = d + fld st0 ; ST = d d + fmul dword [esi + (24*4)] ; ST = d*data[sample+24] d + fadd dword [edi + (24*4)] ; ST = autoc[24]+d*data[sample+24] d + fstp dword [edi + (24*4)] ; autoc[24]+=d*data[sample+24] ST = d + fld st0 ; ST = d d + fmul dword [esi + (23*4)] ; ST = d*data[sample+23] d + fadd dword [edi + (23*4)] ; ST = autoc[23]+d*data[sample+23] d + fstp dword [edi + (23*4)] ; autoc[23]+=d*data[sample+23] ST = d + fld st0 ; ST = d d + fmul dword [esi + (22*4)] ; ST = d*data[sample+22] d + fadd dword [edi + (22*4)] ; ST = autoc[22]+d*data[sample+22] d + fstp dword [edi + (22*4)] ; autoc[22]+=d*data[sample+22] ST = d + fld st0 ; ST = d d + fmul dword [esi + (21*4)] ; ST = d*data[sample+21] d + fadd dword [edi + (21*4)] ; ST = autoc[21]+d*data[sample+21] d + fstp dword [edi + (21*4)] ; autoc[21]+=d*data[sample+21] ST = d + fld st0 ; ST = d d + fmul dword [esi + (20*4)] ; ST = d*data[sample+20] d + fadd dword [edi + (20*4)] ; ST = autoc[20]+d*data[sample+20] d + fstp dword [edi + (20*4)] ; autoc[20]+=d*data[sample+20] ST = d + fld st0 ; ST = d d + fmul dword [esi + (19*4)] ; ST = d*data[sample+19] d + fadd dword [edi + (19*4)] ; ST = autoc[19]+d*data[sample+19] d + fstp dword [edi + (19*4)] ; autoc[19]+=d*data[sample+19] ST = d + fld st0 ; ST = d d + fmul dword [esi + (18*4)] ; ST = d*data[sample+18] d + fadd dword [edi + (18*4)] ; ST = autoc[18]+d*data[sample+18] d + fstp dword [edi + (18*4)] ; autoc[18]+=d*data[sample+18] ST = d + fld st0 ; ST = d d + fmul dword [esi + (17*4)] ; ST = d*data[sample+17] d + fadd dword [edi + (17*4)] ; ST = autoc[17]+d*data[sample+17] d + fstp dword [edi + (17*4)] ; autoc[17]+=d*data[sample+17] ST = d + fld st0 ; ST = d d + fmul dword [esi + (16*4)] ; ST = d*data[sample+16] d + fadd dword [edi + (16*4)] ; ST = autoc[16]+d*data[sample+16] d + fstp dword [edi + (16*4)] ; autoc[16]+=d*data[sample+16] ST = d + fld st0 ; ST = d d + fmul dword [esi + (15*4)] ; ST = d*data[sample+15] d + fadd dword [edi + (15*4)] ; ST = autoc[15]+d*data[sample+15] d + fstp dword [edi + (15*4)] ; autoc[15]+=d*data[sample+15] ST = d + fld st0 ; ST = d d + fmul dword [esi + (14*4)] ; ST = d*data[sample+14] d + fadd dword [edi + (14*4)] ; ST = autoc[14]+d*data[sample+14] d + fstp dword [edi + (14*4)] ; autoc[14]+=d*data[sample+14] ST = d + fld st0 ; ST = d d + fmul dword [esi + (13*4)] ; ST = d*data[sample+13] d + fadd dword [edi + (13*4)] ; ST = autoc[13]+d*data[sample+13] d + fstp dword [edi + (13*4)] ; autoc[13]+=d*data[sample+13] ST = d + fld st0 ; ST = d d + fmul dword [esi + (12*4)] ; ST = d*data[sample+12] d + fadd dword [edi + (12*4)] ; ST = autoc[12]+d*data[sample+12] d + fstp dword [edi + (12*4)] ; autoc[12]+=d*data[sample+12] ST = d + fld st0 ; ST = d d + fmul dword [esi + (11*4)] ; ST = d*data[sample+11] d + fadd dword [edi + (11*4)] ; ST = autoc[11]+d*data[sample+11] d + fstp dword [edi + (11*4)] ; autoc[11]+=d*data[sample+11] ST = d + fld st0 ; ST = d d + fmul dword [esi + (10*4)] ; ST = d*data[sample+10] d + fadd dword [edi + (10*4)] ; ST = autoc[10]+d*data[sample+10] d + fstp dword [edi + (10*4)] ; autoc[10]+=d*data[sample+10] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 9*4)] ; ST = d*data[sample+9] d + fadd dword [edi + ( 9*4)] ; ST = autoc[9]+d*data[sample+9] d + fstp dword [edi + ( 9*4)] ; autoc[9]+=d*data[sample+9] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 8*4)] ; ST = d*data[sample+8] d + fadd dword [edi + ( 8*4)] ; ST = autoc[8]+d*data[sample+8] d + fstp dword [edi + ( 8*4)] ; autoc[8]+=d*data[sample+8] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 7*4)] ; ST = d*data[sample+7] d + fadd dword [edi + ( 7*4)] ; ST = autoc[7]+d*data[sample+7] d + fstp dword [edi + ( 7*4)] ; autoc[7]+=d*data[sample+7] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 6*4)] ; ST = d*data[sample+6] d + fadd dword [edi + ( 6*4)] ; ST = autoc[6]+d*data[sample+6] d + fstp dword [edi + ( 6*4)] ; autoc[6]+=d*data[sample+6] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 5*4)] ; ST = d*data[sample+4] d + fadd dword [edi + ( 5*4)] ; ST = autoc[4]+d*data[sample+4] d + fstp dword [edi + ( 5*4)] ; autoc[4]+=d*data[sample+4] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 4*4)] ; ST = d*data[sample+4] d + fadd dword [edi + ( 4*4)] ; ST = autoc[4]+d*data[sample+4] d + fstp dword [edi + ( 4*4)] ; autoc[4]+=d*data[sample+4] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 3*4)] ; ST = d*data[sample+3] d + fadd dword [edi + ( 3*4)] ; ST = autoc[3]+d*data[sample+3] d + fstp dword [edi + ( 3*4)] ; autoc[3]+=d*data[sample+3] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 2*4)] ; ST = d*data[sample+2] d + fadd dword [edi + ( 2*4)] ; ST = autoc[2]+d*data[sample+2] d + fstp dword [edi + ( 2*4)] ; autoc[2]+=d*data[sample+2] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 1*4)] ; ST = d*data[sample+1] d + fadd dword [edi + ( 1*4)] ; ST = autoc[1]+d*data[sample+1] d + fstp dword [edi + ( 1*4)] ; autoc[1]+=d*data[sample+1] ST = d + fld st0 ; ST = d d + fmul dword [esi] ; ST = d*data[sample] d WATCHOUT: no displacement byte here! + fadd dword [edi] ; ST = autoc[0]+d*data[sample] d WATCHOUT: no displacement byte here! + fstp dword [edi] ; autoc[0]+=d*data[sample] ST = d WATCHOUT: no displacement byte here! +.jumper1_0: + + fstp st0 ; pop d, ST = empty + add esi, byte 4 ; sample++ + dec ecx + jz .loop1_end + fld dword [esi] ; ST = d <- data[sample] + jmp edx +.loop1_end: + + ; for(; sample < data_len; sample++) { + ; d = data[sample]; + ; for(coeff = 0; coeff < data_len - sample; coeff++) + ; autoc[coeff] += d * data[sample+coeff]; + ; } + mov ecx, [esp + 24] ; ecx <- lag + dec ecx ; ecx <- lag - 1 + jz near .end ; skip loop if 0 (i.e. lag == 1) + + fld dword [esi] ; ST = d <- data[sample] + mov eax, ecx ; eax <- lag - 1 == data_len - sample the first time through + ; each iteration is 11 bytes so we need (-eax)*11, so we do (-12*eax + eax) + lea edx, [eax + eax*2] + neg edx + lea edx, [eax + edx*4 + .jumper2_0 - .get_eip2] + call .mov_eip_to_ebx +.get_eip2: + add edx, ebx + inc edx ; compensate for the shorter opcode on the last iteration + inc edx ; compensate for the shorter opcode on the last iteration + inc edx ; compensate for the shorter opcode on the last iteration + jmp edx + + fld st0 ; ST = d d + fmul dword [esi + (31*4)] ; ST = d*data[sample+31] d + fadd dword [edi + (31*4)] ; ST = autoc[31]+d*data[sample+31] d + fstp dword [edi + (31*4)] ; autoc[31]+=d*data[sample+31] ST = d + fld st0 ; ST = d d + fmul dword [esi + (30*4)] ; ST = d*data[sample+30] d + fadd dword [edi + (30*4)] ; ST = autoc[30]+d*data[sample+30] d + fstp dword [edi + (30*4)] ; autoc[30]+=d*data[sample+30] ST = d + fld st0 ; ST = d d + fmul dword [esi + (29*4)] ; ST = d*data[sample+29] d + fadd dword [edi + (29*4)] ; ST = autoc[29]+d*data[sample+29] d + fstp dword [edi + (29*4)] ; autoc[29]+=d*data[sample+29] ST = d + fld st0 ; ST = d d + fmul dword [esi + (28*4)] ; ST = d*data[sample+28] d + fadd dword [edi + (28*4)] ; ST = autoc[28]+d*data[sample+28] d + fstp dword [edi + (28*4)] ; autoc[28]+=d*data[sample+28] ST = d + fld st0 ; ST = d d + fmul dword [esi + (27*4)] ; ST = d*data[sample+27] d + fadd dword [edi + (27*4)] ; ST = autoc[27]+d*data[sample+27] d + fstp dword [edi + (27*4)] ; autoc[27]+=d*data[sample+27] ST = d + fld st0 ; ST = d d + fmul dword [esi + (26*4)] ; ST = d*data[sample+26] d + fadd dword [edi + (26*4)] ; ST = autoc[26]+d*data[sample+26] d + fstp dword [edi + (26*4)] ; autoc[26]+=d*data[sample+26] ST = d + fld st0 ; ST = d d + fmul dword [esi + (25*4)] ; ST = d*data[sample+25] d + fadd dword [edi + (25*4)] ; ST = autoc[25]+d*data[sample+25] d + fstp dword [edi + (25*4)] ; autoc[25]+=d*data[sample+25] ST = d + fld st0 ; ST = d d + fmul dword [esi + (24*4)] ; ST = d*data[sample+24] d + fadd dword [edi + (24*4)] ; ST = autoc[24]+d*data[sample+24] d + fstp dword [edi + (24*4)] ; autoc[24]+=d*data[sample+24] ST = d + fld st0 ; ST = d d + fmul dword [esi + (23*4)] ; ST = d*data[sample+23] d + fadd dword [edi + (23*4)] ; ST = autoc[23]+d*data[sample+23] d + fstp dword [edi + (23*4)] ; autoc[23]+=d*data[sample+23] ST = d + fld st0 ; ST = d d + fmul dword [esi + (22*4)] ; ST = d*data[sample+22] d + fadd dword [edi + (22*4)] ; ST = autoc[22]+d*data[sample+22] d + fstp dword [edi + (22*4)] ; autoc[22]+=d*data[sample+22] ST = d + fld st0 ; ST = d d + fmul dword [esi + (21*4)] ; ST = d*data[sample+21] d + fadd dword [edi + (21*4)] ; ST = autoc[21]+d*data[sample+21] d + fstp dword [edi + (21*4)] ; autoc[21]+=d*data[sample+21] ST = d + fld st0 ; ST = d d + fmul dword [esi + (20*4)] ; ST = d*data[sample+20] d + fadd dword [edi + (20*4)] ; ST = autoc[20]+d*data[sample+20] d + fstp dword [edi + (20*4)] ; autoc[20]+=d*data[sample+20] ST = d + fld st0 ; ST = d d + fmul dword [esi + (19*4)] ; ST = d*data[sample+19] d + fadd dword [edi + (19*4)] ; ST = autoc[19]+d*data[sample+19] d + fstp dword [edi + (19*4)] ; autoc[19]+=d*data[sample+19] ST = d + fld st0 ; ST = d d + fmul dword [esi + (18*4)] ; ST = d*data[sample+18] d + fadd dword [edi + (18*4)] ; ST = autoc[18]+d*data[sample+18] d + fstp dword [edi + (18*4)] ; autoc[18]+=d*data[sample+18] ST = d + fld st0 ; ST = d d + fmul dword [esi + (17*4)] ; ST = d*data[sample+17] d + fadd dword [edi + (17*4)] ; ST = autoc[17]+d*data[sample+17] d + fstp dword [edi + (17*4)] ; autoc[17]+=d*data[sample+17] ST = d + fld st0 ; ST = d d + fmul dword [esi + (16*4)] ; ST = d*data[sample+16] d + fadd dword [edi + (16*4)] ; ST = autoc[16]+d*data[sample+16] d + fstp dword [edi + (16*4)] ; autoc[16]+=d*data[sample+16] ST = d + fld st0 ; ST = d d + fmul dword [esi + (15*4)] ; ST = d*data[sample+15] d + fadd dword [edi + (15*4)] ; ST = autoc[15]+d*data[sample+15] d + fstp dword [edi + (15*4)] ; autoc[15]+=d*data[sample+15] ST = d + fld st0 ; ST = d d + fmul dword [esi + (14*4)] ; ST = d*data[sample+14] d + fadd dword [edi + (14*4)] ; ST = autoc[14]+d*data[sample+14] d + fstp dword [edi + (14*4)] ; autoc[14]+=d*data[sample+14] ST = d + fld st0 ; ST = d d + fmul dword [esi + (13*4)] ; ST = d*data[sample+13] d + fadd dword [edi + (13*4)] ; ST = autoc[13]+d*data[sample+13] d + fstp dword [edi + (13*4)] ; autoc[13]+=d*data[sample+13] ST = d + fld st0 ; ST = d d + fmul dword [esi + (12*4)] ; ST = d*data[sample+12] d + fadd dword [edi + (12*4)] ; ST = autoc[12]+d*data[sample+12] d + fstp dword [edi + (12*4)] ; autoc[12]+=d*data[sample+12] ST = d + fld st0 ; ST = d d + fmul dword [esi + (11*4)] ; ST = d*data[sample+11] d + fadd dword [edi + (11*4)] ; ST = autoc[11]+d*data[sample+11] d + fstp dword [edi + (11*4)] ; autoc[11]+=d*data[sample+11] ST = d + fld st0 ; ST = d d + fmul dword [esi + (10*4)] ; ST = d*data[sample+10] d + fadd dword [edi + (10*4)] ; ST = autoc[10]+d*data[sample+10] d + fstp dword [edi + (10*4)] ; autoc[10]+=d*data[sample+10] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 9*4)] ; ST = d*data[sample+9] d + fadd dword [edi + ( 9*4)] ; ST = autoc[9]+d*data[sample+9] d + fstp dword [edi + ( 9*4)] ; autoc[9]+=d*data[sample+9] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 8*4)] ; ST = d*data[sample+8] d + fadd dword [edi + ( 8*4)] ; ST = autoc[8]+d*data[sample+8] d + fstp dword [edi + ( 8*4)] ; autoc[8]+=d*data[sample+8] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 7*4)] ; ST = d*data[sample+7] d + fadd dword [edi + ( 7*4)] ; ST = autoc[7]+d*data[sample+7] d + fstp dword [edi + ( 7*4)] ; autoc[7]+=d*data[sample+7] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 6*4)] ; ST = d*data[sample+6] d + fadd dword [edi + ( 6*4)] ; ST = autoc[6]+d*data[sample+6] d + fstp dword [edi + ( 6*4)] ; autoc[6]+=d*data[sample+6] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 5*4)] ; ST = d*data[sample+4] d + fadd dword [edi + ( 5*4)] ; ST = autoc[4]+d*data[sample+4] d + fstp dword [edi + ( 5*4)] ; autoc[4]+=d*data[sample+4] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 4*4)] ; ST = d*data[sample+4] d + fadd dword [edi + ( 4*4)] ; ST = autoc[4]+d*data[sample+4] d + fstp dword [edi + ( 4*4)] ; autoc[4]+=d*data[sample+4] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 3*4)] ; ST = d*data[sample+3] d + fadd dword [edi + ( 3*4)] ; ST = autoc[3]+d*data[sample+3] d + fstp dword [edi + ( 3*4)] ; autoc[3]+=d*data[sample+3] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 2*4)] ; ST = d*data[sample+2] d + fadd dword [edi + ( 2*4)] ; ST = autoc[2]+d*data[sample+2] d + fstp dword [edi + ( 2*4)] ; autoc[2]+=d*data[sample+2] ST = d + fld st0 ; ST = d d + fmul dword [esi + ( 1*4)] ; ST = d*data[sample+1] d + fadd dword [edi + ( 1*4)] ; ST = autoc[1]+d*data[sample+1] d + fstp dword [edi + ( 1*4)] ; autoc[1]+=d*data[sample+1] ST = d + fld st0 ; ST = d d + fmul dword [esi] ; ST = d*data[sample] d WATCHOUT: no displacement byte here! + fadd dword [edi] ; ST = autoc[0]+d*data[sample] d WATCHOUT: no displacement byte here! + fstp dword [edi] ; autoc[0]+=d*data[sample] ST = d WATCHOUT: no displacement byte here! +.jumper2_0: + + fstp st0 ; pop d, ST = empty + add esi, byte 4 ; sample++ + dec ecx + jz .loop2_end + add edx, byte 11 ; adjust our inner loop counter by adjusting the jump target + fld dword [esi] ; ST = d <- data[sample] + jmp edx +.loop2_end: + +.end: + pop ebx + pop edi + pop esi + ret + + ALIGN 16 +cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old + ;[esp + 16] == autoc[] + ;[esp + 12] == lag + ;[esp + 8] == data_len + ;[esp + 4] == data[] + + ;ASSERT(lag > 0) + ;ASSERT(lag <= 4) + ;ASSERT(lag <= data_len) + + ; for(coeff = 0; coeff < lag; coeff++) + ; autoc[coeff] = 0.0; + xorps xmm5, xmm5 + + mov edx, [esp + 8] ; edx == data_len + mov eax, [esp + 4] ; eax == &data[sample] <- &data[0] + + movss xmm0, [eax] ; xmm0 = 0,0,0,data[0] + add eax, 4 + movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0] + shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0] +.warmup: ; xmm2 == data[sample-3],data[sample-2],data[sample-1],data[sample] + mulps xmm0, xmm2 ; xmm0 = xmm0 * xmm2 + addps xmm5, xmm0 ; xmm5 += xmm0 * xmm2 + dec edx + jz .loop_end + ALIGN 16 +.loop_start: + ; start by reading the next sample + movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample] + add eax, 4 + shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample] + shufps xmm2, xmm2, 93h ; 93h=2-1-0-3 => xmm2 gets rotated left by one float + movss xmm2, xmm0 + mulps xmm0, xmm2 ; xmm0 = xmm0 * xmm2 + addps xmm5, xmm0 ; xmm5 += xmm0 * xmm2 + dec edx + jnz .loop_start +.loop_end: + ; store autoc + mov edx, [esp + 16] ; edx == autoc + movups [edx], xmm5 + +.end: + ret + + ALIGN 16 +cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old + ;[esp + 16] == autoc[] + ;[esp + 12] == lag + ;[esp + 8] == data_len + ;[esp + 4] == data[] + + ;ASSERT(lag > 0) + ;ASSERT(lag <= 8) + ;ASSERT(lag <= data_len) + + ; for(coeff = 0; coeff < lag; coeff++) + ; autoc[coeff] = 0.0; + xorps xmm5, xmm5 + xorps xmm6, xmm6 + + mov edx, [esp + 8] ; edx == data_len + mov eax, [esp + 4] ; eax == &data[sample] <- &data[0] + + movss xmm0, [eax] ; xmm0 = 0,0,0,data[0] + add eax, 4 + movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0] + shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0] + movaps xmm1, xmm0 ; xmm1 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0] + xorps xmm3, xmm3 ; xmm3 = 0,0,0,0 +.warmup: ; xmm3:xmm2 == data[sample-7],data[sample-6],...,data[sample] + mulps xmm0, xmm2 + mulps xmm1, xmm3 ; xmm1:xmm0 = xmm1:xmm0 * xmm3:xmm2 + addps xmm5, xmm0 + addps xmm6, xmm1 ; xmm6:xmm5 += xmm1:xmm0 * xmm3:xmm2 + dec edx + jz .loop_end + ALIGN 16 +.loop_start: + ; start by reading the next sample + movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample] + ; here we reorder the instructions; see the (#) indexes for a logical order + shufps xmm2, xmm2, 93h ; (3) 93h=2-1-0-3 => xmm2 gets rotated left by one float + add eax, 4 ; (0) + shufps xmm3, xmm3, 93h ; (4) 93h=2-1-0-3 => xmm3 gets rotated left by one float + shufps xmm0, xmm0, 0 ; (1) xmm0 = data[sample],data[sample],data[sample],data[sample] + movss xmm3, xmm2 ; (5) + movaps xmm1, xmm0 ; (2) xmm1 = data[sample],data[sample],data[sample],data[sample] + movss xmm2, xmm0 ; (6) + mulps xmm1, xmm3 ; (8) + mulps xmm0, xmm2 ; (7) xmm1:xmm0 = xmm1:xmm0 * xmm3:xmm2 + addps xmm6, xmm1 ; (10) + addps xmm5, xmm0 ; (9) xmm6:xmm5 += xmm1:xmm0 * xmm3:xmm2 + dec edx + jnz .loop_start +.loop_end: + ; store autoc + mov edx, [esp + 16] ; edx == autoc + movups [edx], xmm5 + movups [edx + 16], xmm6 + +.end: + ret + + ALIGN 16 +cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old + ;[esp + 16] == autoc[] + ;[esp + 12] == lag + ;[esp + 8] == data_len + ;[esp + 4] == data[] + + ;ASSERT(lag > 0) + ;ASSERT(lag <= 12) + ;ASSERT(lag <= data_len) + + ; for(coeff = 0; coeff < lag; coeff++) + ; autoc[coeff] = 0.0; + xorps xmm5, xmm5 + xorps xmm6, xmm6 + xorps xmm7, xmm7 + + mov edx, [esp + 8] ; edx == data_len + mov eax, [esp + 4] ; eax == &data[sample] <- &data[0] + + movss xmm0, [eax] ; xmm0 = 0,0,0,data[0] + add eax, 4 + movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0] + shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0] + xorps xmm3, xmm3 ; xmm3 = 0,0,0,0 + xorps xmm4, xmm4 ; xmm4 = 0,0,0,0 +.warmup: ; xmm3:xmm2 == data[sample-7],data[sample-6],...,data[sample] + movaps xmm1, xmm0 + mulps xmm1, xmm2 + addps xmm5, xmm1 + movaps xmm1, xmm0 + mulps xmm1, xmm3 + addps xmm6, xmm1 + mulps xmm0, xmm4 + addps xmm7, xmm0 ; xmm7:xmm6:xmm5 += xmm0:xmm0:xmm0 * xmm4:xmm3:xmm2 + dec edx + jz .loop_end + ALIGN 16 +.loop_start: + ; start by reading the next sample + movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample] + add eax, 4 + shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample] + + ; shift xmm4:xmm3:xmm2 left by one float + shufps xmm2, xmm2, 93h ; 93h=2-1-0-3 => xmm2 gets rotated left by one float + shufps xmm3, xmm3, 93h ; 93h=2-1-0-3 => xmm3 gets rotated left by one float + shufps xmm4, xmm4, 93h ; 93h=2-1-0-3 => xmm4 gets rotated left by one float + movss xmm4, xmm3 + movss xmm3, xmm2 + movss xmm2, xmm0 + + ; xmm7:xmm6:xmm5 += xmm0:xmm0:xmm0 * xmm4:xmm3:xmm2 + movaps xmm1, xmm0 + mulps xmm1, xmm2 + addps xmm5, xmm1 + movaps xmm1, xmm0 + mulps xmm1, xmm3 + addps xmm6, xmm1 + mulps xmm0, xmm4 + addps xmm7, xmm0 + + dec edx + jnz .loop_start +.loop_end: + ; store autoc + mov edx, [esp + 16] ; edx == autoc + movups [edx], xmm5 + movups [edx + 16], xmm6 + movups [edx + 32], xmm7 + +.end: + ret + + ALIGN 16 +cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old + ;[ebp + 20] == autoc[] + ;[ebp + 16] == lag + ;[ebp + 12] == data_len + ;[ebp + 8] == data[] + ;[esp] == __m128 + ;[esp + 16] == __m128 + + push ebp + mov ebp, esp + and esp, -16 ; stack realign for SSE instructions 'movaps' and 'addps' + sub esp, 32 + + ;ASSERT(lag > 0) + ;ASSERT(lag <= 12) + ;ASSERT(lag <= data_len) + ;ASSERT(data_len > 0) + + ; for(coeff = 0; coeff < lag; coeff++) + ; autoc[coeff] = 0.0; + xorps xmm5, xmm5 + xorps xmm6, xmm6 + movaps [esp], xmm5 + movaps [esp + 16], xmm6 + + mov edx, [ebp + 12] ; edx == data_len + mov eax, [ebp + 8] ; eax == &data[sample] <- &data[0] + + movss xmm0, [eax] ; xmm0 = 0,0,0,data[0] + add eax, 4 + movaps xmm1, xmm0 ; xmm1 = 0,0,0,data[0] + shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0] + xorps xmm2, xmm2 ; xmm2 = 0,0,0,0 + xorps xmm3, xmm3 ; xmm3 = 0,0,0,0 + xorps xmm4, xmm4 ; xmm4 = 0,0,0,0 + movaps xmm7, xmm0 + mulps xmm7, xmm1 + addps xmm5, xmm7 + dec edx + jz .loop_end + ALIGN 16 +.loop_start: + ; start by reading the next sample + movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample] + add eax, 4 + shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample] + + ; shift xmm4:xmm3:xmm2:xmm1 left by one float + shufps xmm1, xmm1, 93h + shufps xmm2, xmm2, 93h + shufps xmm3, xmm3, 93h + shufps xmm4, xmm4, 93h + movss xmm4, xmm3 + movss xmm3, xmm2 + movss xmm2, xmm1 + movss xmm1, xmm0 + + ; xmmB:xmmA:xmm6:xmm5 += xmm0:xmm0:xmm0:xmm0 * xmm4:xmm3:xmm2:xmm1 + movaps xmm7, xmm0 + mulps xmm7, xmm1 + addps xmm5, xmm7 + movaps xmm7, xmm0 + mulps xmm7, xmm2 + addps xmm6, xmm7 + movaps xmm7, xmm0 + mulps xmm7, xmm3 + mulps xmm0, xmm4 + addps xmm7, [esp] + addps xmm0, [esp + 16] + movaps [esp], xmm7 + movaps [esp + 16], xmm0 + + dec edx + jnz .loop_start +.loop_end: + ; store autoc + mov edx, [ebp + 20] ; edx == autoc + movups [edx], xmm5 + movups [edx + 16], xmm6 + movaps xmm5, [esp] + movaps xmm6, [esp + 16] + movups [edx + 32], xmm5 + movups [edx + 48], xmm6 +.end: + mov esp, ebp + pop ebp + ret + +;void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +; +; for(i = 0; i < data_len; i++) { +; sum = 0; +; for(j = 0; j < order; j++) +; sum += qlp_coeff[j] * data[i-j-1]; +; residual[i] = data[i] - (sum >> lp_quantization); +; } +; + ALIGN 16 +cident FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32 + ;[esp + 40] residual[] + ;[esp + 36] lp_quantization + ;[esp + 32] order + ;[esp + 28] qlp_coeff[] + ;[esp + 24] data_len + ;[esp + 20] data[] + + ;ASSERT(order > 0) + + push ebp + push ebx + push esi + push edi + + mov esi, [esp + 20] ; esi = data[] + mov edi, [esp + 40] ; edi = residual[] + mov eax, [esp + 32] ; eax = order + mov ebx, [esp + 24] ; ebx = data_len + + test ebx, ebx + jz near .end ; do nothing if data_len == 0 +.begin: + cmp eax, byte 1 + jg short .i_1more + + mov ecx, [esp + 28] + mov edx, [ecx] ; edx = qlp_coeff[0] + mov eax, [esi - 4] ; eax = data[-1] + mov ecx, [esp + 36] ; cl = lp_quantization + ALIGN 16 +.i_1_loop_i: + imul eax, edx + sar eax, cl + neg eax + add eax, [esi] + mov [edi], eax + mov eax, [esi] + add edi, byte 4 + add esi, byte 4 + dec ebx + jnz .i_1_loop_i + + jmp .end + +.i_1more: + cmp eax, byte 32 ; for order <= 32 there is a faster routine + jbe short .i_32 + + ; This version is here just for completeness, since FLAC__MAX_LPC_ORDER == 32 + ALIGN 16 +.i_32more_loop_i: + xor ebp, ebp + mov ecx, [esp + 32] + mov edx, ecx + shl edx, 2 + add edx, [esp + 28] + neg ecx + ALIGN 16 +.i_32more_loop_j: + sub edx, byte 4 + mov eax, [edx] + imul eax, [esi + 4 * ecx] + add ebp, eax + inc ecx + jnz short .i_32more_loop_j + + mov ecx, [esp + 36] + sar ebp, cl + neg ebp + add ebp, [esi] + mov [edi], ebp + add esi, byte 4 + add edi, byte 4 + + dec ebx + jnz .i_32more_loop_i + + jmp .end + +.mov_eip_to_eax: + mov eax, [esp] + ret + +.i_32: + sub edi, esi + neg eax + lea edx, [eax + eax * 8 + .jumper_0 - .get_eip0] + call .mov_eip_to_eax +.get_eip0: + add edx, eax + inc edx + mov eax, [esp + 28] ; eax = qlp_coeff[] + xor ebp, ebp + jmp edx + + mov ecx, [eax + 124] + imul ecx, [esi - 128] + add ebp, ecx + mov ecx, [eax + 120] + imul ecx, [esi - 124] + add ebp, ecx + mov ecx, [eax + 116] + imul ecx, [esi - 120] + add ebp, ecx + mov ecx, [eax + 112] + imul ecx, [esi - 116] + add ebp, ecx + mov ecx, [eax + 108] + imul ecx, [esi - 112] + add ebp, ecx + mov ecx, [eax + 104] + imul ecx, [esi - 108] + add ebp, ecx + mov ecx, [eax + 100] + imul ecx, [esi - 104] + add ebp, ecx + mov ecx, [eax + 96] + imul ecx, [esi - 100] + add ebp, ecx + mov ecx, [eax + 92] + imul ecx, [esi - 96] + add ebp, ecx + mov ecx, [eax + 88] + imul ecx, [esi - 92] + add ebp, ecx + mov ecx, [eax + 84] + imul ecx, [esi - 88] + add ebp, ecx + mov ecx, [eax + 80] + imul ecx, [esi - 84] + add ebp, ecx + mov ecx, [eax + 76] + imul ecx, [esi - 80] + add ebp, ecx + mov ecx, [eax + 72] + imul ecx, [esi - 76] + add ebp, ecx + mov ecx, [eax + 68] + imul ecx, [esi - 72] + add ebp, ecx + mov ecx, [eax + 64] + imul ecx, [esi - 68] + add ebp, ecx + mov ecx, [eax + 60] + imul ecx, [esi - 64] + add ebp, ecx + mov ecx, [eax + 56] + imul ecx, [esi - 60] + add ebp, ecx + mov ecx, [eax + 52] + imul ecx, [esi - 56] + add ebp, ecx + mov ecx, [eax + 48] + imul ecx, [esi - 52] + add ebp, ecx + mov ecx, [eax + 44] + imul ecx, [esi - 48] + add ebp, ecx + mov ecx, [eax + 40] + imul ecx, [esi - 44] + add ebp, ecx + mov ecx, [eax + 36] + imul ecx, [esi - 40] + add ebp, ecx + mov ecx, [eax + 32] + imul ecx, [esi - 36] + add ebp, ecx + mov ecx, [eax + 28] + imul ecx, [esi - 32] + add ebp, ecx + mov ecx, [eax + 24] + imul ecx, [esi - 28] + add ebp, ecx + mov ecx, [eax + 20] + imul ecx, [esi - 24] + add ebp, ecx + mov ecx, [eax + 16] + imul ecx, [esi - 20] + add ebp, ecx + mov ecx, [eax + 12] + imul ecx, [esi - 16] + add ebp, ecx + mov ecx, [eax + 8] + imul ecx, [esi - 12] + add ebp, ecx + mov ecx, [eax + 4] + imul ecx, [esi - 8] + add ebp, ecx + mov ecx, [eax] ; there is one byte missing + imul ecx, [esi - 4] + add ebp, ecx +.jumper_0: + + mov ecx, [esp + 36] + sar ebp, cl + neg ebp + add ebp, [esi] + mov [edi + esi], ebp + add esi, byte 4 + + dec ebx + jz short .end + xor ebp, ebp + jmp edx + +.end: + pop edi + pop esi + pop ebx + pop ebp + ret + +; WATCHOUT: this routine works on 16 bit data which means bits-per-sample for +; the channel and qlp_coeffs must be <= 16. Especially note that this routine +; cannot be used for side-channel coded 16bps channels since the effective bps +; is 17. + ALIGN 16 +cident FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx + ;[esp + 40] residual[] + ;[esp + 36] lp_quantization + ;[esp + 32] order + ;[esp + 28] qlp_coeff[] + ;[esp + 24] data_len + ;[esp + 20] data[] + + ;ASSERT(order > 0) + + push ebp + push ebx + push esi + push edi + + mov esi, [esp + 20] ; esi = data[] + mov edi, [esp + 40] ; edi = residual[] + mov eax, [esp + 32] ; eax = order + mov ebx, [esp + 24] ; ebx = data_len + + test ebx, ebx + jz near .end ; do nothing if data_len == 0 + dec ebx + test ebx, ebx + jz near .last_one + + mov edx, [esp + 28] ; edx = qlp_coeff[] + movd mm6, [esp + 36] ; mm6 = 0:lp_quantization + mov ebp, esp + + and esp, 0xfffffff8 + + xor ecx, ecx +.copy_qlp_loop: + push word [edx + 4 * ecx] + inc ecx + cmp ecx, eax + jnz short .copy_qlp_loop + + and ecx, 0x3 + test ecx, ecx + je short .za_end + sub ecx, byte 4 +.za_loop: + push word 0 + inc eax + inc ecx + jnz short .za_loop +.za_end: + + movq mm5, [esp + 2 * eax - 8] + movd mm4, [esi - 16] + punpckldq mm4, [esi - 12] + movd mm0, [esi - 8] + punpckldq mm0, [esi - 4] + packssdw mm4, mm0 + + cmp eax, byte 4 + jnbe short .mmx_4more + + ALIGN 16 +.mmx_4_loop_i: + movd mm1, [esi] + movq mm3, mm4 + punpckldq mm1, [esi + 4] + psrlq mm4, 16 + movq mm0, mm1 + psllq mm0, 48 + por mm4, mm0 + movq mm2, mm4 + psrlq mm4, 16 + pxor mm0, mm0 + punpckhdq mm0, mm1 + pmaddwd mm3, mm5 + pmaddwd mm2, mm5 + psllq mm0, 16 + por mm4, mm0 + movq mm0, mm3 + punpckldq mm3, mm2 + punpckhdq mm0, mm2 + paddd mm3, mm0 + psrad mm3, mm6 + psubd mm1, mm3 + movd [edi], mm1 + punpckhdq mm1, mm1 + movd [edi + 4], mm1 + + add edi, byte 8 + add esi, byte 8 + + sub ebx, 2 + jg .mmx_4_loop_i + jmp .mmx_end + +.mmx_4more: + shl eax, 2 + neg eax + add eax, byte 16 + + ALIGN 16 +.mmx_4more_loop_i: + movd mm1, [esi] + punpckldq mm1, [esi + 4] + movq mm3, mm4 + psrlq mm4, 16 + movq mm0, mm1 + psllq mm0, 48 + por mm4, mm0 + movq mm2, mm4 + psrlq mm4, 16 + pxor mm0, mm0 + punpckhdq mm0, mm1 + pmaddwd mm3, mm5 + pmaddwd mm2, mm5 + psllq mm0, 16 + por mm4, mm0 + + mov ecx, esi + add ecx, eax + mov edx, esp + + ALIGN 16 +.mmx_4more_loop_j: + movd mm0, [ecx - 16] + movd mm7, [ecx - 8] + punpckldq mm0, [ecx - 12] + punpckldq mm7, [ecx - 4] + packssdw mm0, mm7 + pmaddwd mm0, [edx] + punpckhdq mm7, mm7 + paddd mm3, mm0 + movd mm0, [ecx - 12] + punpckldq mm0, [ecx - 8] + punpckldq mm7, [ecx] + packssdw mm0, mm7 + pmaddwd mm0, [edx] + paddd mm2, mm0 + + add edx, byte 8 + add ecx, byte 16 + cmp ecx, esi + jnz .mmx_4more_loop_j + + movq mm0, mm3 + punpckldq mm3, mm2 + punpckhdq mm0, mm2 + paddd mm3, mm0 + psrad mm3, mm6 + psubd mm1, mm3 + movd [edi], mm1 + punpckhdq mm1, mm1 + movd [edi + 4], mm1 + + add edi, byte 8 + add esi, byte 8 + + sub ebx, 2 + jg near .mmx_4more_loop_i + +.mmx_end: + emms + mov esp, ebp +.last_one: + mov eax, [esp + 32] + inc ebx + jnz near FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32.begin + +.end: + pop edi + pop esi + pop ebx + pop ebp + ret + +; ********************************************************************** +; +; void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) +; { +; unsigned i, j; +; FLAC__int32 sum; +; +; FLAC__ASSERT(order > 0); +; +; for(i = 0; i < data_len; i++) { +; sum = 0; +; for(j = 0; j < order; j++) +; sum += qlp_coeff[j] * data[i-j-1]; +; data[i] = residual[i] + (sum >> lp_quantization); +; } +; } + ALIGN 16 +cident FLAC__lpc_restore_signal_asm_ia32 + ;[esp + 40] data[] + ;[esp + 36] lp_quantization + ;[esp + 32] order + ;[esp + 28] qlp_coeff[] + ;[esp + 24] data_len + ;[esp + 20] residual[] + + ;ASSERT(order > 0) + + push ebp + push ebx + push esi + push edi + + mov esi, [esp + 20] ; esi = residual[] + mov edi, [esp + 40] ; edi = data[] + mov eax, [esp + 32] ; eax = order + mov ebx, [esp + 24] ; ebx = data_len + + test ebx, ebx + jz near .end ; do nothing if data_len == 0 + +.begin: + cmp eax, byte 1 + jg short .x87_1more + + mov ecx, [esp + 28] + mov edx, [ecx] + mov eax, [edi - 4] + mov ecx, [esp + 36] + ALIGN 16 +.x87_1_loop_i: + imul eax, edx + sar eax, cl + add eax, [esi] + mov [edi], eax + add esi, byte 4 + add edi, byte 4 + dec ebx + jnz .x87_1_loop_i + + jmp .end + +.x87_1more: + cmp eax, byte 32 ; for order <= 32 there is a faster routine + jbe short .x87_32 + + ; This version is here just for completeness, since FLAC__MAX_LPC_ORDER == 32 + ALIGN 16 +.x87_32more_loop_i: + xor ebp, ebp + mov ecx, [esp + 32] + mov edx, ecx + shl edx, 2 + add edx, [esp + 28] + neg ecx + ALIGN 16 +.x87_32more_loop_j: + sub edx, byte 4 + mov eax, [edx] + imul eax, [edi + 4 * ecx] + add ebp, eax + inc ecx + jnz short .x87_32more_loop_j + + mov ecx, [esp + 36] + sar ebp, cl + add ebp, [esi] + mov [edi], ebp + add edi, byte 4 + add esi, byte 4 + + dec ebx + jnz .x87_32more_loop_i + + jmp .end + +.mov_eip_to_eax: + mov eax, [esp] + ret + +.x87_32: + sub esi, edi + neg eax + lea edx, [eax + eax * 8 + .jumper_0 - .get_eip0] + call .mov_eip_to_eax +.get_eip0: + add edx, eax + inc edx ; compensate for the shorter opcode on the last iteration + mov eax, [esp + 28] ; eax = qlp_coeff[] + xor ebp, ebp + jmp edx + + mov ecx, [eax + 124] ; ecx = qlp_coeff[31] + imul ecx, [edi - 128] ; ecx = qlp_coeff[31] * data[i-32] + add ebp, ecx ; sum += qlp_coeff[31] * data[i-32] + mov ecx, [eax + 120] ; ecx = qlp_coeff[30] + imul ecx, [edi - 124] ; ecx = qlp_coeff[30] * data[i-31] + add ebp, ecx ; sum += qlp_coeff[30] * data[i-31] + mov ecx, [eax + 116] ; ecx = qlp_coeff[29] + imul ecx, [edi - 120] ; ecx = qlp_coeff[29] * data[i-30] + add ebp, ecx ; sum += qlp_coeff[29] * data[i-30] + mov ecx, [eax + 112] ; ecx = qlp_coeff[28] + imul ecx, [edi - 116] ; ecx = qlp_coeff[28] * data[i-29] + add ebp, ecx ; sum += qlp_coeff[28] * data[i-29] + mov ecx, [eax + 108] ; ecx = qlp_coeff[27] + imul ecx, [edi - 112] ; ecx = qlp_coeff[27] * data[i-28] + add ebp, ecx ; sum += qlp_coeff[27] * data[i-28] + mov ecx, [eax + 104] ; ecx = qlp_coeff[26] + imul ecx, [edi - 108] ; ecx = qlp_coeff[26] * data[i-27] + add ebp, ecx ; sum += qlp_coeff[26] * data[i-27] + mov ecx, [eax + 100] ; ecx = qlp_coeff[25] + imul ecx, [edi - 104] ; ecx = qlp_coeff[25] * data[i-26] + add ebp, ecx ; sum += qlp_coeff[25] * data[i-26] + mov ecx, [eax + 96] ; ecx = qlp_coeff[24] + imul ecx, [edi - 100] ; ecx = qlp_coeff[24] * data[i-25] + add ebp, ecx ; sum += qlp_coeff[24] * data[i-25] + mov ecx, [eax + 92] ; ecx = qlp_coeff[23] + imul ecx, [edi - 96] ; ecx = qlp_coeff[23] * data[i-24] + add ebp, ecx ; sum += qlp_coeff[23] * data[i-24] + mov ecx, [eax + 88] ; ecx = qlp_coeff[22] + imul ecx, [edi - 92] ; ecx = qlp_coeff[22] * data[i-23] + add ebp, ecx ; sum += qlp_coeff[22] * data[i-23] + mov ecx, [eax + 84] ; ecx = qlp_coeff[21] + imul ecx, [edi - 88] ; ecx = qlp_coeff[21] * data[i-22] + add ebp, ecx ; sum += qlp_coeff[21] * data[i-22] + mov ecx, [eax + 80] ; ecx = qlp_coeff[20] + imul ecx, [edi - 84] ; ecx = qlp_coeff[20] * data[i-21] + add ebp, ecx ; sum += qlp_coeff[20] * data[i-21] + mov ecx, [eax + 76] ; ecx = qlp_coeff[19] + imul ecx, [edi - 80] ; ecx = qlp_coeff[19] * data[i-20] + add ebp, ecx ; sum += qlp_coeff[19] * data[i-20] + mov ecx, [eax + 72] ; ecx = qlp_coeff[18] + imul ecx, [edi - 76] ; ecx = qlp_coeff[18] * data[i-19] + add ebp, ecx ; sum += qlp_coeff[18] * data[i-19] + mov ecx, [eax + 68] ; ecx = qlp_coeff[17] + imul ecx, [edi - 72] ; ecx = qlp_coeff[17] * data[i-18] + add ebp, ecx ; sum += qlp_coeff[17] * data[i-18] + mov ecx, [eax + 64] ; ecx = qlp_coeff[16] + imul ecx, [edi - 68] ; ecx = qlp_coeff[16] * data[i-17] + add ebp, ecx ; sum += qlp_coeff[16] * data[i-17] + mov ecx, [eax + 60] ; ecx = qlp_coeff[15] + imul ecx, [edi - 64] ; ecx = qlp_coeff[15] * data[i-16] + add ebp, ecx ; sum += qlp_coeff[15] * data[i-16] + mov ecx, [eax + 56] ; ecx = qlp_coeff[14] + imul ecx, [edi - 60] ; ecx = qlp_coeff[14] * data[i-15] + add ebp, ecx ; sum += qlp_coeff[14] * data[i-15] + mov ecx, [eax + 52] ; ecx = qlp_coeff[13] + imul ecx, [edi - 56] ; ecx = qlp_coeff[13] * data[i-14] + add ebp, ecx ; sum += qlp_coeff[13] * data[i-14] + mov ecx, [eax + 48] ; ecx = qlp_coeff[12] + imul ecx, [edi - 52] ; ecx = qlp_coeff[12] * data[i-13] + add ebp, ecx ; sum += qlp_coeff[12] * data[i-13] + mov ecx, [eax + 44] ; ecx = qlp_coeff[11] + imul ecx, [edi - 48] ; ecx = qlp_coeff[11] * data[i-12] + add ebp, ecx ; sum += qlp_coeff[11] * data[i-12] + mov ecx, [eax + 40] ; ecx = qlp_coeff[10] + imul ecx, [edi - 44] ; ecx = qlp_coeff[10] * data[i-11] + add ebp, ecx ; sum += qlp_coeff[10] * data[i-11] + mov ecx, [eax + 36] ; ecx = qlp_coeff[ 9] + imul ecx, [edi - 40] ; ecx = qlp_coeff[ 9] * data[i-10] + add ebp, ecx ; sum += qlp_coeff[ 9] * data[i-10] + mov ecx, [eax + 32] ; ecx = qlp_coeff[ 8] + imul ecx, [edi - 36] ; ecx = qlp_coeff[ 8] * data[i- 9] + add ebp, ecx ; sum += qlp_coeff[ 8] * data[i- 9] + mov ecx, [eax + 28] ; ecx = qlp_coeff[ 7] + imul ecx, [edi - 32] ; ecx = qlp_coeff[ 7] * data[i- 8] + add ebp, ecx ; sum += qlp_coeff[ 7] * data[i- 8] + mov ecx, [eax + 24] ; ecx = qlp_coeff[ 6] + imul ecx, [edi - 28] ; ecx = qlp_coeff[ 6] * data[i- 7] + add ebp, ecx ; sum += qlp_coeff[ 6] * data[i- 7] + mov ecx, [eax + 20] ; ecx = qlp_coeff[ 5] + imul ecx, [edi - 24] ; ecx = qlp_coeff[ 5] * data[i- 6] + add ebp, ecx ; sum += qlp_coeff[ 5] * data[i- 6] + mov ecx, [eax + 16] ; ecx = qlp_coeff[ 4] + imul ecx, [edi - 20] ; ecx = qlp_coeff[ 4] * data[i- 5] + add ebp, ecx ; sum += qlp_coeff[ 4] * data[i- 5] + mov ecx, [eax + 12] ; ecx = qlp_coeff[ 3] + imul ecx, [edi - 16] ; ecx = qlp_coeff[ 3] * data[i- 4] + add ebp, ecx ; sum += qlp_coeff[ 3] * data[i- 4] + mov ecx, [eax + 8] ; ecx = qlp_coeff[ 2] + imul ecx, [edi - 12] ; ecx = qlp_coeff[ 2] * data[i- 3] + add ebp, ecx ; sum += qlp_coeff[ 2] * data[i- 3] + mov ecx, [eax + 4] ; ecx = qlp_coeff[ 1] + imul ecx, [edi - 8] ; ecx = qlp_coeff[ 1] * data[i- 2] + add ebp, ecx ; sum += qlp_coeff[ 1] * data[i- 2] + mov ecx, [eax] ; ecx = qlp_coeff[ 0] (NOTE: one byte missing from instruction) + imul ecx, [edi - 4] ; ecx = qlp_coeff[ 0] * data[i- 1] + add ebp, ecx ; sum += qlp_coeff[ 0] * data[i- 1] +.jumper_0: + + mov ecx, [esp + 36] + sar ebp, cl ; ebp = (sum >> lp_quantization) + add ebp, [esi + edi] ; ebp = residual[i] + (sum >> lp_quantization) + mov [edi], ebp ; data[i] = residual[i] + (sum >> lp_quantization) + add edi, byte 4 + + dec ebx + jz short .end + xor ebp, ebp + jmp edx + +.end: + pop edi + pop esi + pop ebx + pop ebp + ret + +; WATCHOUT: this routine works on 16 bit data which means bits-per-sample for +; the channel and qlp_coeffs must be <= 16. Especially note that this routine +; cannot be used for side-channel coded 16bps channels since the effective bps +; is 17. +; WATCHOUT: this routine requires that each data array have a buffer of up to +; 3 zeroes in front (at negative indices) for alignment purposes, i.e. for each +; channel n, data[n][-1] through data[n][-3] should be accessible and zero. + ALIGN 16 +cident FLAC__lpc_restore_signal_asm_ia32_mmx + ;[esp + 40] data[] + ;[esp + 36] lp_quantization + ;[esp + 32] order + ;[esp + 28] qlp_coeff[] + ;[esp + 24] data_len + ;[esp + 20] residual[] + + ;ASSERT(order > 0) + + push ebp + push ebx + push esi + push edi + + mov esi, [esp + 20] + mov edi, [esp + 40] + mov eax, [esp + 32] + mov ebx, [esp + 24] + + test ebx, ebx + jz near .end ; do nothing if data_len == 0 + cmp eax, byte 4 + jb near FLAC__lpc_restore_signal_asm_ia32.begin + + mov edx, [esp + 28] + movd mm6, [esp + 36] + mov ebp, esp + + and esp, 0xfffffff8 + + xor ecx, ecx +.copy_qlp_loop: + push word [edx + 4 * ecx] + inc ecx + cmp ecx, eax + jnz short .copy_qlp_loop + + and ecx, 0x3 + test ecx, ecx + je short .za_end + sub ecx, byte 4 +.za_loop: + push word 0 + inc eax + inc ecx + jnz short .za_loop +.za_end: + + movq mm5, [esp + 2 * eax - 8] + movd mm4, [edi - 16] + punpckldq mm4, [edi - 12] + movd mm0, [edi - 8] + punpckldq mm0, [edi - 4] + packssdw mm4, mm0 + + cmp eax, byte 4 + jnbe short .mmx_4more + + ALIGN 16 +.mmx_4_loop_i: + movq mm7, mm4 + pmaddwd mm7, mm5 + movq mm0, mm7 + punpckhdq mm7, mm7 + paddd mm7, mm0 + psrad mm7, mm6 + movd mm1, [esi] + paddd mm7, mm1 + movd [edi], mm7 + psllq mm7, 48 + psrlq mm4, 16 + por mm4, mm7 + + add esi, byte 4 + add edi, byte 4 + + dec ebx + jnz .mmx_4_loop_i + jmp .mmx_end +.mmx_4more: + shl eax, 2 + neg eax + add eax, byte 16 + ALIGN 16 +.mmx_4more_loop_i: + mov ecx, edi + add ecx, eax + mov edx, esp + + movq mm7, mm4 + pmaddwd mm7, mm5 + + ALIGN 16 +.mmx_4more_loop_j: + movd mm0, [ecx - 16] + punpckldq mm0, [ecx - 12] + movd mm1, [ecx - 8] + punpckldq mm1, [ecx - 4] + packssdw mm0, mm1 + pmaddwd mm0, [edx] + paddd mm7, mm0 + + add edx, byte 8 + add ecx, byte 16 + cmp ecx, edi + jnz .mmx_4more_loop_j + + movq mm0, mm7 + punpckhdq mm7, mm7 + paddd mm7, mm0 + psrad mm7, mm6 + movd mm1, [esi] + paddd mm7, mm1 + movd [edi], mm7 + psllq mm7, 48 + psrlq mm4, 16 + por mm4, mm7 + + add esi, byte 4 + add edi, byte 4 + + dec ebx + jnz short .mmx_4more_loop_i +.mmx_end: + emms + mov esp, ebp + +.end: + pop edi + pop esi + pop ebx + pop ebp + ret + + +; ********************************************************************** +; +;void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +; { +; unsigned i, j; +; FLAC__int64 sum; +; +; FLAC__ASSERT(order > 0); +; +; for(i = 0; i < data_len; i++) { +; sum = 0; +; for(j = 0; j < order; j++) +; sum += qlp_coeff[j] * (FLAC__int64)data[i-j-1]; +; residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); +; } +; } + ALIGN 16 +cident FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32 + ;[esp + 40] residual[] + ;[esp + 36] lp_quantization + ;[esp + 32] order + ;[esp + 28] qlp_coeff[] + ;[esp + 24] data_len + ;[esp + 20] data[] + + ;ASSERT(order > 0) + ;ASSERT(order <= 32) + ;ASSERT(lp_quantization <= 31) + + push ebp + push ebx + push esi + push edi + + mov ebx, [esp + 24] ; ebx = data_len + test ebx, ebx + jz near .end ; do nothing if data_len == 0 + +.begin: + mov eax, [esp + 32] ; eax = order + cmp eax, 1 + jg short .i_32 + + mov esi, [esp + 40] ; esi = residual[] + mov edi, [esp + 20] ; edi = data[] + mov ecx, [esp + 28] ; ecx = qlp_coeff[] + mov ebp, [ecx] ; ebp = qlp_coeff[0] + mov eax, [edi - 4] ; eax = data[-1] + mov ecx, [esp + 36] ; cl = lp_quantization + ALIGN 16 +.i_1_loop_i: + imul ebp ; edx:eax = qlp_coeff[0] * (FLAC__int64)data[i-1] + shrd eax, edx, cl ; 0 <= lp_quantization <= 15 + neg eax + add eax, [edi] + mov [esi], eax + mov eax, [edi] + add esi, 4 + add edi, 4 + dec ebx + jnz .i_1_loop_i + jmp .end + +.mov_eip_to_eax: + mov eax, [esp] + ret + +.i_32: ; eax = order + neg eax + add eax, eax + lea ebp, [eax + eax * 4 + .jumper_0 - .get_eip0] + call .mov_eip_to_eax +.get_eip0: + add ebp, eax + inc ebp ; compensate for the shorter opcode on the last iteration + + mov ebx, [esp + 28] ; ebx = qlp_coeff[] + mov edi, [esp + 20] ; edi = data[] + sub [esp + 40], edi ; residual[] -= data[] + + xor ecx, ecx + xor esi, esi + jmp ebp + +;eax = -- +;edx = -- +;ecx = 0 +;esi = 0 +; +;ebx = qlp_coeff[] +;edi = data[] +;ebp = @address + + mov eax, [ebx + 124] ; eax = qlp_coeff[31] + imul dword [edi - 128] ; edx:eax = qlp_coeff[31] * data[i-32] + add ecx, eax + adc esi, edx ; sum += qlp_coeff[31] * data[i-32] + + mov eax, [ebx + 120] ; eax = qlp_coeff[30] + imul dword [edi - 124] ; edx:eax = qlp_coeff[30] * data[i-31] + add ecx, eax + adc esi, edx ; sum += qlp_coeff[30] * data[i-31] + + mov eax, [ebx + 116] + imul dword [edi - 120] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 112] + imul dword [edi - 116] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 108] + imul dword [edi - 112] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 104] + imul dword [edi - 108] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 100] + imul dword [edi - 104] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 96] + imul dword [edi - 100] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 92] + imul dword [edi - 96] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 88] + imul dword [edi - 92] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 84] + imul dword [edi - 88] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 80] + imul dword [edi - 84] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 76] + imul dword [edi - 80] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 72] + imul dword [edi - 76] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 68] + imul dword [edi - 72] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 64] + imul dword [edi - 68] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 60] + imul dword [edi - 64] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 56] + imul dword [edi - 60] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 52] + imul dword [edi - 56] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 48] + imul dword [edi - 52] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 44] + imul dword [edi - 48] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 40] + imul dword [edi - 44] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 36] + imul dword [edi - 40] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 32] + imul dword [edi - 36] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 28] + imul dword [edi - 32] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 24] + imul dword [edi - 28] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 20] + imul dword [edi - 24] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 16] + imul dword [edi - 20] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 12] + imul dword [edi - 16] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 8] + imul dword [edi - 12] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 4] + imul dword [edi - 8] + add ecx, eax + adc esi, edx + + mov eax, [ebx] ; eax = qlp_coeff[ 0] (NOTE: one byte missing from instruction) + imul dword [edi - 4] ; edx:eax = qlp_coeff[ 0] * data[i- 1] + add ecx, eax + adc esi, edx ; sum += qlp_coeff[ 0] * data[i- 1] + +.jumper_0: + mov edx, ecx +;esi:edx = sum + mov ecx, [esp + 36] ; cl = lp_quantization + shrd edx, esi, cl ; edx = (sum >> lp_quantization) +;eax = -- +;ecx = -- +;edx = sum >> lp_q +;esi = -- + neg edx ; edx = -(sum >> lp_quantization) + mov eax, [esp + 40] ; residual[] - data[] + add edx, [edi] ; edx = data[i] - (sum >> lp_quantization) + mov [edi + eax], edx + add edi, 4 + + dec dword [esp + 24] + jz short .end + xor ecx, ecx + xor esi, esi + jmp ebp + +.end: + pop edi + pop esi + pop ebx + pop ebp + ret + +; ********************************************************************** +; +; void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) +; { +; unsigned i, j; +; FLAC__int64 sum; +; +; FLAC__ASSERT(order > 0); +; +; for(i = 0; i < data_len; i++) { +; sum = 0; +; for(j = 0; j < order; j++) +; sum += qlp_coeff[j] * (FLAC__int64)data[i-j-1]; +; data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); +; } +; } + ALIGN 16 +cident FLAC__lpc_restore_signal_wide_asm_ia32 + ;[esp + 40] data[] + ;[esp + 36] lp_quantization + ;[esp + 32] order + ;[esp + 28] qlp_coeff[] + ;[esp + 24] data_len + ;[esp + 20] residual[] + + ;ASSERT(order > 0) + ;ASSERT(order <= 32) + ;ASSERT(lp_quantization <= 31) + + push ebp + push ebx + push esi + push edi + + mov ebx, [esp + 24] ; ebx = data_len + test ebx, ebx + jz near .end ; do nothing if data_len == 0 + +.begin: + mov eax, [esp + 32] ; eax = order + cmp eax, 1 + jg short .x87_32 + + mov esi, [esp + 20] ; esi = residual[] + mov edi, [esp + 40] ; edi = data[] + mov ecx, [esp + 28] ; ecx = qlp_coeff[] + mov ebp, [ecx] ; ebp = qlp_coeff[0] + mov eax, [edi - 4] ; eax = data[-1] + mov ecx, [esp + 36] ; cl = lp_quantization + ALIGN 16 +.x87_1_loop_i: + imul ebp ; edx:eax = qlp_coeff[0] * (FLAC__int64)data[i-1] + shrd eax, edx, cl ; 0 <= lp_quantization <= 15 +; + add eax, [esi] + mov [edi], eax +; + add esi, 4 + add edi, 4 + dec ebx + jnz .x87_1_loop_i + jmp .end + +.mov_eip_to_eax: + mov eax, [esp] + ret + +.x87_32: ; eax = order + neg eax + add eax, eax + lea ebp, [eax + eax * 4 + .jumper_0 - .get_eip0] + call .mov_eip_to_eax +.get_eip0: + add ebp, eax + inc ebp ; compensate for the shorter opcode on the last iteration + + mov ebx, [esp + 28] ; ebx = qlp_coeff[] + mov edi, [esp + 40] ; esi = data[] + sub [esp + 20], edi ; residual[] -= data[] + + xor ecx, ecx + xor esi, esi + jmp ebp + +;eax = -- +;edx = -- +;ecx = 0 +;esi = 0 +; +;ebx = qlp_coeff[] +;edi = data[] +;ebp = @address + + mov eax, [ebx + 124] ; eax = qlp_coeff[31] + imul dword [edi - 128] ; edx:eax = qlp_coeff[31] * data[i-32] + add ecx, eax + adc esi, edx ; sum += qlp_coeff[31] * data[i-32] + + mov eax, [ebx + 120] ; eax = qlp_coeff[30] + imul dword [edi - 124] ; edx:eax = qlp_coeff[30] * data[i-31] + add ecx, eax + adc esi, edx ; sum += qlp_coeff[30] * data[i-31] + + mov eax, [ebx + 116] + imul dword [edi - 120] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 112] + imul dword [edi - 116] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 108] + imul dword [edi - 112] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 104] + imul dword [edi - 108] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 100] + imul dword [edi - 104] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 96] + imul dword [edi - 100] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 92] + imul dword [edi - 96] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 88] + imul dword [edi - 92] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 84] + imul dword [edi - 88] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 80] + imul dword [edi - 84] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 76] + imul dword [edi - 80] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 72] + imul dword [edi - 76] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 68] + imul dword [edi - 72] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 64] + imul dword [edi - 68] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 60] + imul dword [edi - 64] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 56] + imul dword [edi - 60] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 52] + imul dword [edi - 56] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 48] + imul dword [edi - 52] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 44] + imul dword [edi - 48] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 40] + imul dword [edi - 44] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 36] + imul dword [edi - 40] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 32] + imul dword [edi - 36] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 28] + imul dword [edi - 32] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 24] + imul dword [edi - 28] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 20] + imul dword [edi - 24] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 16] + imul dword [edi - 20] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 12] + imul dword [edi - 16] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 8] + imul dword [edi - 12] + add ecx, eax + adc esi, edx + + mov eax, [ebx + 4] + imul dword [edi - 8] + add ecx, eax + adc esi, edx + + mov eax, [ebx] ; eax = qlp_coeff[ 0] (NOTE: one byte missing from instruction) + imul dword [edi - 4] ; edx:eax = qlp_coeff[ 0] * data[i- 1] + add ecx, eax + adc esi, edx ; sum += qlp_coeff[ 0] * data[i- 1] + +.jumper_0: + mov edx, ecx +;esi:edx = sum + mov ecx, [esp + 36] ; cl = lp_quantization + shrd edx, esi, cl ; edx = (sum >> lp_quantization) +;eax = -- +;ecx = -- +;edx = sum >> lp_q +;esi = -- +; + mov eax, [esp + 20] ; residual[] - data[] + add edx, [edi + eax] ; edx = residual[i] + (sum >> lp_quantization) + mov [edi], edx ; data[i] = residual[i] + (sum >> lp_quantization) + add edi, 4 + + dec dword [esp + 24] + jz short .end + xor ecx, ecx + xor esi, esi + jmp ebp + +.end: + pop edi + pop esi + pop ebx + pop ebp + ret + +; end diff --git a/deps/flac-1.3.2/src/libFLAC/ia32/nasm.h b/deps/flac-1.3.2/src/libFLAC/ia32/nasm.h new file mode 100644 index 0000000..ff479bf --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ia32/nasm.h @@ -0,0 +1,90 @@ +; libFLAC - Free Lossless Audio Codec library +; Copyright (C) 2001-2009 Josh Coalson +; Copyright (C) 2011-2016 Xiph.Org Foundation +; +; 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 the Xiph.org Foundation 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 FOUNDATION 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. + + bits 32 + +%ifdef OBJ_FORMAT_win32 + %define FLAC__PUBLIC_NEEDS_UNDERSCORE + %idefine code_section section .text align=16 class=CODE use32 + %idefine data_section section .data align=32 class=DATA use32 + %idefine bss_section section .bss align=32 class=DATA use32 +%elifdef OBJ_FORMAT_aout + %define FLAC__PUBLIC_NEEDS_UNDERSCORE + %idefine code_section section .text + %idefine data_section section .data + %idefine bss_section section .bss +%elifdef OBJ_FORMAT_aoutb + %define FLAC__PUBLIC_NEEDS_UNDERSCORE + %idefine code_section section .text + %idefine data_section section .data + %idefine bss_section section .bss +%elifdef OBJ_FORMAT_macho + %define FLAC__PUBLIC_NEEDS_UNDERSCORE + %idefine code_section section .text + %idefine data_section section .data + %idefine bss_section section .bss +%elifdef OBJ_FORMAT_elf + %idefine code_section section .text align=16 + %idefine data_section section .data align=32 + %idefine bss_section section .bss align=32 +%else + %error unsupported object format! ; this directive doesn't really work here +%endif + +%imacro cglobal 1 + %ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE + global _%1 + %else + %if __NASM_MAJOR__ >= 2 + global %1:function hidden + %else + global %1 + %endif + %endif +%endmacro + +%imacro cextern 1 + %ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE + extern _%1 + %else + extern %1 + %endif +%endmacro + +%imacro cident 1 +_%1: +%1: +%endmacro + +%ifdef OBJ_FORMAT_elf +section .note.GNU-stack progbits noalloc noexec nowrite align=1 +%endif + diff --git a/deps/flac-1.3.2/src/libFLAC/include/Makefile.am b/deps/flac-1.3.2/src/libFLAC/include/Makefile.am new file mode 100644 index 0000000..99e98a4 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/Makefile.am @@ -0,0 +1,32 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +SUBDIRS = private protected diff --git a/deps/flac-1.3.2/src/libFLAC/include/Makefile.in b/deps/flac-1.3.2/src/libFLAC/include/Makefile.in new file mode 100644 index 0000000..9d19efb --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/Makefile.in @@ -0,0 +1,691 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libFLAC/include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-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 \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +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_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = private protected +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/libFLAC/include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libFLAC/include/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 + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + 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" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + 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; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + 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 +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 Makefile +distclean-am: clean-am distclean-generic 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 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: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean 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-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-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/Makefile.am b/deps/flac-1.3.2/src/libFLAC/include/private/Makefile.am new file mode 100644 index 0000000..49bcda7 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/Makefile.am @@ -0,0 +1,53 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +noinst_HEADERS = \ + all.h \ + bitmath.h \ + bitreader.h \ + bitwriter.h \ + cpu.h \ + crc.h \ + fixed.h \ + float.h \ + format.h \ + lpc.h \ + macros.h \ + md5.h \ + memory.h \ + metadata.h \ + ogg_decoder_aspect.h \ + ogg_encoder_aspect.h \ + ogg_helper.h \ + ogg_mapping.h \ + stream_encoder.h \ + stream_encoder_framing.h \ + window.h diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/Makefile.in b/deps/flac-1.3.2/src/libFLAC/include/private/Makefile.in new file mode 100644 index 0000000..d288902 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/Makefile.in @@ -0,0 +1,601 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libFLAC/include/private +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_HEADERS = \ + all.h \ + bitmath.h \ + bitreader.h \ + bitwriter.h \ + cpu.h \ + crc.h \ + fixed.h \ + float.h \ + format.h \ + lpc.h \ + macros.h \ + md5.h \ + memory.h \ + metadata.h \ + ogg_decoder_aspect.h \ + ogg_encoder_aspect.h \ + ogg_helper.h \ + ogg_mapping.h \ + stream_encoder.h \ + stream_encoder_framing.h \ + window.h + +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 src/libFLAC/include/private/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libFLAC/include/private/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 + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 $(HEADERS) +installdirs: +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 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-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f 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: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + 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-man 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 tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/all.h b/deps/flac-1.3.2/src/libFLAC/include/private/all.h new file mode 100644 index 0000000..7715962 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/all.h @@ -0,0 +1,50 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__ALL_H +#define FLAC__PRIVATE__ALL_H + +#include "bitmath.h" +#include "bitreader.h" +#include "bitwriter.h" +#include "cpu.h" +#include "crc.h" +#include "fixed.h" +#include "float.h" +#include "format.h" +#include "lpc.h" +#include "md5.h" +#include "memory.h" +#include "metadata.h" +#include "stream_encoder_framing.h" + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/bitmath.h b/deps/flac-1.3.2/src/libFLAC/include/private/bitmath.h new file mode 100644 index 0000000..9c75f85 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/bitmath.h @@ -0,0 +1,210 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__BITMATH_H +#define FLAC__PRIVATE__BITMATH_H + +#include "FLAC/ordinals.h" +#include "FLAC/assert.h" + +#include "share/compat.h" + +#if defined(_MSC_VER) +#include <intrin.h> /* for _BitScanReverse* */ +#endif + +/* Will never be emitted for MSVC, GCC, Intel compilers */ +static inline unsigned int FLAC__clz_soft_uint32(FLAC__uint32 word) +{ + static const unsigned char byte_to_unary_table[] = { + 8, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + return word > 0xffffff ? byte_to_unary_table[word >> 24] : + word > 0xffff ? byte_to_unary_table[word >> 16] + 8 : + word > 0xff ? byte_to_unary_table[word >> 8] + 16 : + byte_to_unary_table[word] + 24; +} + +static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v) +{ +/* Never used with input 0 */ + FLAC__ASSERT(v > 0); +#if defined(__INTEL_COMPILER) + return _bit_scan_reverse(v) ^ 31U; +#elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on + * -march= setting or to a software routine in exotic machines. */ + return __builtin_clz(v); +#elif defined(_MSC_VER) + { + unsigned long idx; + _BitScanReverse(&idx, v); + return idx ^ 31U; + } +#else + return FLAC__clz_soft_uint32(v); +#endif +} + +/* Used when 64-bit bsr/clz is unavailable; can use 32-bit bsr/clz when possible */ +static inline unsigned int FLAC__clz_soft_uint64(FLAC__uint64 word) +{ + return (FLAC__uint32)(word>>32) ? FLAC__clz_uint32((FLAC__uint32)(word>>32)) : + FLAC__clz_uint32((FLAC__uint32)word) + 32; +} + +static inline unsigned int FLAC__clz_uint64(FLAC__uint64 v) +{ + /* Never used with input 0 */ + FLAC__ASSERT(v > 0); +#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + return __builtin_clzll(v); +#elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64)) + { + unsigned long idx; + _BitScanReverse64(&idx, v); + return idx ^ 63U; + } +#else + return FLAC__clz_soft_uint64(v); +#endif +} + +/* These two functions work with input 0 */ +static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v) +{ + if (!v) + return 32; + return FLAC__clz_uint32(v); +} + +static inline unsigned int FLAC__clz2_uint64(FLAC__uint64 v) +{ + if (!v) + return 64; + return FLAC__clz_uint64(v); +} + +/* An example of what FLAC__bitmath_ilog2() computes: + * + * ilog2( 0) = assertion failure + * ilog2( 1) = 0 + * ilog2( 2) = 1 + * ilog2( 3) = 1 + * ilog2( 4) = 2 + * ilog2( 5) = 2 + * ilog2( 6) = 2 + * ilog2( 7) = 2 + * ilog2( 8) = 3 + * ilog2( 9) = 3 + * ilog2(10) = 3 + * ilog2(11) = 3 + * ilog2(12) = 3 + * ilog2(13) = 3 + * ilog2(14) = 3 + * ilog2(15) = 3 + * ilog2(16) = 4 + * ilog2(17) = 4 + * ilog2(18) = 4 + */ + +static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) +{ + FLAC__ASSERT(v > 0); +#if defined(__INTEL_COMPILER) + return _bit_scan_reverse(v); +#elif defined(_MSC_VER) + { + unsigned long idx; + _BitScanReverse(&idx, v); + return idx; + } +#else + return FLAC__clz_uint32(v) ^ 31U; +#endif +} + +static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) +{ + FLAC__ASSERT(v > 0); +#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + return __builtin_clzll(v) ^ 63U; +/* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */ +#elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64)) + { + unsigned long idx; + _BitScanReverse64(&idx, v); + return idx; + } +#else +/* Brain-damaged compilers will use the fastest possible way that is, + de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) + (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain). +*/ + { + static const unsigned char DEBRUIJN_IDX64[64]={ + 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, + 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, + 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, + 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 + }; + v|= v>>1; + v|= v>>2; + v|= v>>4; + v|= v>>8; + v|= v>>16; + v|= v>>32; + v= (v>>1)+1; + return DEBRUIJN_IDX64[v*FLAC__U64L(0x218A392CD3D5DBF)>>58&0x3F]; + } +#endif +} + +unsigned FLAC__bitmath_silog2(FLAC__int64 v); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/bitreader.h b/deps/flac-1.3.2/src/libFLAC/include/private/bitreader.h new file mode 100644 index 0000000..7c73165 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/bitreader.h @@ -0,0 +1,91 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__BITREADER_H +#define FLAC__PRIVATE__BITREADER_H + +#include <stdio.h> /* for FILE */ +#include "FLAC/ordinals.h" +#include "cpu.h" + +/* + * opaque structure definition + */ +struct FLAC__BitReader; +typedef struct FLAC__BitReader FLAC__BitReader; + +typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data); + +/* + * construction, deletion, initialization, etc functions + */ +FLAC__BitReader *FLAC__bitreader_new(void); +void FLAC__bitreader_delete(FLAC__BitReader *br); +FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd); +void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */ +FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); +void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); + +/* + * CRC functions + */ +void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed); +FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br); + +/* + * info functions + */ +FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); +unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); +unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); + +/* + * read functions + */ + +FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits); +FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits); +FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits); +FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/ +FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */ +FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals); /* WATCHOUT: does not CRC the read data! */ +FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals); /* WATCHOUT: does not CRC the read data! */ +FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val); +FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter); +FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); +#if 0 /* UNUSED */ +FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter); +FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter); +#endif +FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen); +FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen); +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/bitwriter.h b/deps/flac-1.3.2/src/libFLAC/include/private/bitwriter.h new file mode 100644 index 0000000..ef3ad1b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/bitwriter.h @@ -0,0 +1,104 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__BITWRITER_H +#define FLAC__PRIVATE__BITWRITER_H + +#include <stdio.h> /* for FILE */ +#include "FLAC/ordinals.h" + +/* + * opaque structure definition + */ +struct FLAC__BitWriter; +typedef struct FLAC__BitWriter FLAC__BitWriter; + +/* + * construction, deletion, initialization, etc functions + */ +FLAC__BitWriter *FLAC__bitwriter_new(void); +void FLAC__bitwriter_delete(FLAC__BitWriter *bw); +FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw); +void FLAC__bitwriter_free(FLAC__BitWriter *bw); /* does not 'free(buffer)' */ +void FLAC__bitwriter_clear(FLAC__BitWriter *bw); +void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out); + +/* + * CRC functions + * + * non-const *bw because they have to cal FLAC__bitwriter_get_buffer() + */ +FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc); +FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc); + +/* + * info functions + */ +FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw); +unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw); /* can be called anytime, returns total # of bits unconsumed */ + +/* + * direct buffer access + * + * there may be no calls on the bitwriter between get and release. + * the bitwriter continues to own the returned buffer. + * before get, bitwriter MUST be byte aligned: check with FLAC__bitwriter_is_byte_aligned() + */ +FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes); +void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw); + +/* + * write functions + */ +FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits); +FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits); +FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits); +FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits); +FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/ +FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals); +FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val); +unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter); +#if 0 /* UNUSED */ +unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter); +unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned val, unsigned parameter); +#endif +FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter); +FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter); +#if 0 /* UNUSED */ +FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter); +FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned val, unsigned parameter); +#endif +FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val); +FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val); +FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/cpu.h b/deps/flac-1.3.2/src/libFLAC/include/private/cpu.h new file mode 100644 index 0000000..7c65180 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/cpu.h @@ -0,0 +1,186 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__CPU_H +#define FLAC__PRIVATE__CPU_H + +#include "FLAC/ordinals.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef FLAC__CPU_X86_64 + +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define FLAC__CPU_X86_64 +#endif + +#endif + +#ifndef FLAC__CPU_IA32 + +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86) +#define FLAC__CPU_IA32 +#endif + +#endif + + +#if FLAC__HAS_X86INTRIN +/* SSE intrinsics support by ICC/MSVC/GCC */ +#if defined __INTEL_COMPILER + #define FLAC__SSE_TARGET(x) + #define FLAC__SSE_SUPPORTED 1 + #define FLAC__SSE2_SUPPORTED 1 + #if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */ + #define FLAC__SSSE3_SUPPORTED 1 + #define FLAC__SSE4_1_SUPPORTED 1 + #endif + #if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */ + #define FLAC__AVX_SUPPORTED 1 + #endif + #if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */ + #define FLAC__AVX2_SUPPORTED 1 + #define FLAC__FMA_SUPPORTED 1 + #endif +#elif defined _MSC_VER + #define FLAC__SSE_TARGET(x) + #define FLAC__SSE_SUPPORTED 1 + #define FLAC__SSE2_SUPPORTED 1 + #if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */ + #define FLAC__SSSE3_SUPPORTED 1 + #define FLAC__SSE4_1_SUPPORTED 1 + #endif + #if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */ + #define FLAC__AVX_SUPPORTED 1 + #endif + #if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */ + #define FLAC__AVX2_SUPPORTED 1 + #define FLAC__FMA_SUPPORTED 1 + #endif +#elif defined __GNUC__ + #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* since GCC 4.9 -msse.. compiler options aren't necessary */ + #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) + #define FLAC__SSE_SUPPORTED 1 + #define FLAC__SSE2_SUPPORTED 1 + #define FLAC__SSSE3_SUPPORTED 1 + #define FLAC__SSE4_1_SUPPORTED 1 +#ifdef FLAC__USE_AVX + #define FLAC__AVX_SUPPORTED 1 + #define FLAC__AVX2_SUPPORTED 1 + #define FLAC__FMA_SUPPORTED 1 +#endif + #else /* for GCC older than 4.9 */ + #define FLAC__SSE_TARGET(x) + #ifdef __SSE__ + #define FLAC__SSE_SUPPORTED 1 + #endif + #ifdef __SSE2__ + #define FLAC__SSE2_SUPPORTED 1 + #endif + #ifdef __SSSE3__ + #define FLAC__SSSE3_SUPPORTED 1 + #endif + #ifdef __SSE4_1__ + #define FLAC__SSE4_1_SUPPORTED 1 + #endif + #ifdef __AVX__ + #define FLAC__AVX_SUPPORTED 1 + #endif + #ifdef __AVX2__ + #define FLAC__AVX2_SUPPORTED 1 + #endif + #ifdef __FMA__ + #define FLAC__FMA_SUPPORTED 1 + #endif + #endif /* GCC version */ +#endif /* compiler version */ +#endif /* intrinsics support */ + + +#ifndef FLAC__AVX_SUPPORTED +#define FLAC__AVX_SUPPORTED 0 +#endif + +typedef enum { + FLAC__CPUINFO_TYPE_IA32, + FLAC__CPUINFO_TYPE_X86_64, + FLAC__CPUINFO_TYPE_UNKNOWN +} FLAC__CPUInfo_Type; + +typedef struct { + FLAC__bool intel; + + FLAC__bool cmov; + FLAC__bool mmx; + FLAC__bool sse; + FLAC__bool sse2; + + FLAC__bool sse3; + FLAC__bool ssse3; + FLAC__bool sse41; + FLAC__bool sse42; + FLAC__bool avx; + FLAC__bool avx2; + FLAC__bool fma; +} FLAC__CPUInfo_IA32; + +typedef struct { + FLAC__bool intel; + + FLAC__bool sse3; + FLAC__bool ssse3; + FLAC__bool sse41; + FLAC__bool sse42; + FLAC__bool avx; + FLAC__bool avx2; + FLAC__bool fma; +} FLAC__CPUInfo_x86; + + +typedef struct { + FLAC__bool use_asm; + FLAC__CPUInfo_Type type; + FLAC__CPUInfo_IA32 ia32; + FLAC__CPUInfo_x86 x86; +} FLAC__CPUInfo; + +void FLAC__cpu_info(FLAC__CPUInfo *info); + +FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void); + +void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx); + +void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/crc.h b/deps/flac-1.3.2/src/libFLAC/include/private/crc.h new file mode 100644 index 0000000..294f60e --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/crc.h @@ -0,0 +1,62 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__CRC_H +#define FLAC__PRIVATE__CRC_H + +#include "FLAC/ordinals.h" + +/* 8 bit CRC generator, MSB shifted first +** polynomial = x^8 + x^2 + x^1 + x^0 +** init = 0 +*/ +extern FLAC__byte const FLAC__crc8_table[256]; +#define FLAC__CRC8_UPDATE(data, crc) (crc) = FLAC__crc8_table[(crc) ^ (data)]; +void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc); +void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc); +FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len); + +/* 16 bit CRC generator, MSB shifted first +** polynomial = x^16 + x^15 + x^2 + x^0 +** init = 0 +*/ +extern unsigned const FLAC__crc16_table[256]; + +#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) +/* this alternate may be faster on some systems/compilers */ +#if 0 +#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff) +#endif + +unsigned FLAC__crc16(const FLAC__byte *data, unsigned len); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/fixed.h b/deps/flac-1.3.2/src/libFLAC/include/private/fixed.h new file mode 100644 index 0000000..68cdfce --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/fixed.h @@ -0,0 +1,107 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__FIXED_H +#define FLAC__PRIVATE__FIXED_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "private/cpu.h" +#include "private/float.h" +#include "FLAC/format.h" + +/* + * FLAC__fixed_compute_best_predictor() + * -------------------------------------------------------------------- + * Compute the best fixed predictor and the expected bits-per-sample + * of the residual signal for each order. The _wide() version uses + * 64-bit integers which is statistically necessary when bits-per- + * sample + log2(blocksize) > 30 + * + * IN data[0,data_len-1] + * IN data_len + * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] + */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY +unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# ifndef FLAC__NO_ASM +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +# endif +# ifdef FLAC__SSSE3_SUPPORTED +unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +# endif +# endif +# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM +unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# endif +# endif +#else +unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#endif + +/* + * FLAC__fixed_compute_residual() + * -------------------------------------------------------------------- + * Compute the residual signal obtained from sutracting the predicted + * signal from the original. + * + * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) + * IN data_len length of original signal + * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order + * OUT residual[0,data_len-1] residual signal + */ +void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]); + +/* + * FLAC__fixed_restore_signal() + * -------------------------------------------------------------------- + * Restore the original signal by summing the residual and the + * predictor. + * + * IN residual[0,data_len-1] residual signal + * IN data_len length of original signal + * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order + * *** IMPORTANT: the caller must pass in the historical samples: + * IN data[-order,-1] previously-reconstructed historical samples + * OUT data[0,data_len-1] original signal + */ +void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/float.h b/deps/flac-1.3.2/src/libFLAC/include/private/float.h new file mode 100644 index 0000000..12ece60 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/float.h @@ -0,0 +1,95 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__FLOAT_H +#define FLAC__PRIVATE__FLOAT_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "FLAC/ordinals.h" + +/* + * All the code in libFLAC that uses float and double + * should be protected by checks of the macro + * FLAC__INTEGER_ONLY_LIBRARY. + * + */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY +/* + * FLAC__real is the basic floating point type used in LPC analysis. + * + * WATCHOUT: changing FLAC__real will change the signatures of many + * functions that have assembly language equivalents and break them. + */ +typedef float FLAC__real; +#else +/* + * The convention for FLAC__fixedpoint is to use the upper 16 bits + * for the integer part and lower 16 bits for the fractional part. + */ +typedef FLAC__int32 FLAC__fixedpoint; +extern const FLAC__fixedpoint FLAC__FP_ZERO; +extern const FLAC__fixedpoint FLAC__FP_ONE_HALF; +extern const FLAC__fixedpoint FLAC__FP_ONE; +extern const FLAC__fixedpoint FLAC__FP_LN2; +extern const FLAC__fixedpoint FLAC__FP_E; + +#define FLAC__fixedpoint_trunc(x) ((x)>>16) + +#define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) ) + +#define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) ) + +/* + * FLAC__fixedpoint_log2() + * -------------------------------------------------------------------- + * Returns the base-2 logarithm of the fixed-point number 'x' using an + * algorithm by Knuth for x >= 1.0 + * + * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must + * be < 32 and evenly divisible by 4 (0 is OK but not very precise). + * + * 'precision' roughly limits the number of iterations that are done; + * use (unsigned)(-1) for maximum precision. + * + * If 'x' is less than one -- that is, x < (1<<fracbits) -- then this + * function will punt and return 0. + * + * The return value will also have 'fracbits' fractional bits. + */ +FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision); + +#endif + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/format.h b/deps/flac-1.3.2/src/libFLAC/include/private/format.h new file mode 100644 index 0000000..5b9cfbd --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/format.h @@ -0,0 +1,45 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__FORMAT_H +#define FLAC__PRIVATE__FORMAT_H + +#include "FLAC/format.h" + +unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order); +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize); +unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order); +void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); +void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); +FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/lpc.h b/deps/flac-1.3.2/src/libFLAC/include/private/lpc.h new file mode 100644 index 0000000..6eb02be --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/lpc.h @@ -0,0 +1,250 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__LPC_H +#define FLAC__PRIVATE__LPC_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "private/cpu.h" +#include "private/float.h" +#include "FLAC/format.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +/* + * FLAC__lpc_window_data() + * -------------------------------------------------------------------- + * Applies the given window to the data. + * OPT: asm implementation + * + * IN in[0,data_len-1] + * IN window[0,data_len-1] + * OUT out[0,lag-1] + * IN data_len + */ +void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len); + +/* + * FLAC__lpc_compute_autocorrelation() + * -------------------------------------------------------------------- + * Compute the autocorrelation for lags between 0 and lag-1. + * Assumes data[] outside of [0,data_len-1] == 0. + * Asserts that lag > 0. + * + * IN data[0,data_len-1] + * IN data_len + * IN 0 < lag <= data_len + * OUT autoc[0,lag-1] + */ +void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +#ifndef FLAC__NO_ASM +# ifdef FLAC__CPU_IA32 +# ifdef FLAC__HAS_NASM +void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +# endif +# endif +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE_SUPPORTED +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +# endif +# endif +#endif + +/* + * FLAC__lpc_compute_lp_coefficients() + * -------------------------------------------------------------------- + * Computes LP coefficients for orders 1..max_order. + * Do not call if autoc[0] == 0.0. This means the signal is zero + * and there is no point in calculating a predictor. + * + * IN autoc[0,max_order] autocorrelation values + * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute + * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order + * *** IMPORTANT: + * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched + * OUT error[0,max_order-1] error for each order (more + * specifically, the variance of + * the error signal times # of + * samples in the signal) + * + * Example: if max_order is 9, the LP coefficients for order 9 will be + * in lp_coeff[8][0,8], the LP coefficients for order 8 will be + * in lp_coeff[7][0,7], etc. + */ +void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]); + +/* + * FLAC__lpc_quantize_coefficients() + * -------------------------------------------------------------------- + * Quantizes the LP coefficients. NOTE: precision + bits_per_sample + * must be less than 32 (sizeof(FLAC__int32)*8). + * + * IN lp_coeff[0,order-1] LP coefficients + * IN order LP order + * IN FLAC__MIN_QLP_COEFF_PRECISION < precision + * desired precision (in bits, including sign + * bit) of largest coefficient + * OUT qlp_coeff[0,order-1] quantized coefficients + * OUT shift # of bits to shift right to get approximated + * LP coefficients. NOTE: could be negative. + * RETURN 0 => quantization OK + * 1 => coefficients require too much shifting for *shift to + * fit in the LPC subframe header. 'shift' is unset. + * 2 => coefficients are all zero, which is bad. 'shift' is + * unset. + */ +int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift); + +/* + * FLAC__lpc_compute_residual_from_qlp_coefficients() + * -------------------------------------------------------------------- + * Compute the residual signal obtained from sutracting the predicted + * signal from the original. + * + * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) + * IN data_len length of original signal + * IN qlp_coeff[0,order-1] quantized LP coefficients + * IN order > 0 LP order + * IN lp_quantization quantization of LP coefficients in bits + * OUT residual[0,data_len-1] residual signal + */ +void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +#ifndef FLAC__NO_ASM +# ifdef FLAC__CPU_IA32 +# ifdef FLAC__HAS_NASM +void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# endif +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# ifdef FLAC__SSE4_1_SUPPORTED +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# ifdef FLAC__AVX2_SUPPORTED +void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# endif +#endif + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + +/* + * FLAC__lpc_restore_signal() + * -------------------------------------------------------------------- + * Restore the original signal by summing the residual and the + * predictor. + * + * IN residual[0,data_len-1] residual signal + * IN data_len length of original signal + * IN qlp_coeff[0,order-1] quantized LP coefficients + * IN order > 0 LP order + * IN lp_quantization quantization of LP coefficients in bits + * *** IMPORTANT: the caller must pass in the historical samples: + * IN data[-order,-1] previously-reconstructed historical samples + * OUT data[0,data_len-1] original signal + */ +void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +#ifndef FLAC__NO_ASM +# ifdef FLAC__CPU_IA32 +# ifdef FLAC__HAS_NASM +void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +# endif /* FLAC__HAS_NASM */ +# endif /* FLAC__CPU_IA32 */ +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +# endif +# ifdef FLAC__SSE4_1_SUPPORTED +void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +# endif +# endif +#endif /* FLAC__NO_ASM */ + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +/* + * FLAC__lpc_compute_expected_bits_per_residual_sample() + * -------------------------------------------------------------------- + * Compute the expected number of bits per residual signal sample + * based on the LP error (which is related to the residual variance). + * + * IN lpc_error >= 0.0 error returned from calculating LP coefficients + * IN total_samples > 0 # of samples in residual signal + * RETURN expected bits per sample + */ +double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, unsigned total_samples); +double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale); + +/* + * FLAC__lpc_compute_best_order() + * -------------------------------------------------------------------- + * Compute the best order from the array of signal errors returned + * during coefficient computation. + * + * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients + * IN max_order > 0 max LP order + * IN total_samples > 0 # of samples in residual signal + * IN overhead_bits_per_order # of bits overhead for each increased LP order + * (includes warmup sample size and quantized LP coefficient) + * RETURN [1,max_order] best order + */ +unsigned FLAC__lpc_compute_best_order(const double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order); + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/macros.h b/deps/flac-1.3.2/src/libFLAC/include/private/macros.h new file mode 100644 index 0000000..a5d9a90 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/macros.h @@ -0,0 +1,71 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2012-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__MACROS_H +#define FLAC__PRIVATE__MACROS_H + +#if defined(__GNUC__) && (__GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + +#define flac_max(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) + +#define MIN_PASTE(A,B) A##B +#define MIN_IMPL(A,B,L) ({ \ + __typeof__(A) MIN_PASTE(__a,L) = (A); \ + __typeof__(B) MIN_PASTE(__b,L) = (B); \ + MIN_PASTE(__a,L) < MIN_PASTE(__b,L) ? MIN_PASTE(__a,L) : MIN_PASTE(__b,L); \ + }) + +#define flac_min(A,B) MIN_IMPL(A,B,__COUNTER__) + +/* Whatever other unix that has sys/param.h */ +#elif defined(HAVE_SYS_PARAM_H) +#define flac_max(a,b) MAX(a,b) +#define flac_min(a,b) MIN(a,b) + +/* Windows VS has them in stdlib.h.. XXX:Untested */ +#elif defined(_MSC_VER) +#include <stdlib.h> +#define flac_max(a,b) __max(a,b) +#define flac_min(a,b) __min(a,b) +#endif + +#ifndef MIN +#define MIN(x,y) ((x) <= (y) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x,y) ((x) >= (y) ? (x) : (y)) +#endif + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/md5.h b/deps/flac-1.3.2/src/libFLAC/include/private/md5.h new file mode 100644 index 0000000..c665ab3 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/md5.h @@ -0,0 +1,50 @@ +#ifndef FLAC__PRIVATE__MD5_H +#define FLAC__PRIVATE__MD5_H + +/* + * This is the header file for the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' + * header definitions; now uses stuff from dpkg's config.h + * - Ian Jackson <ijackson@nyx.cs.du.edu>. + * Still in the public domain. + * + * Josh Coalson: made some changes to integrate with libFLAC. + * Still in the public domain, with no warranty. + */ + +#include "FLAC/ordinals.h" + +typedef union { + FLAC__byte *p8; + FLAC__int16 *p16; + FLAC__int32 *p32; +} FLAC__multibyte; + +typedef struct { + FLAC__uint32 in[16]; + FLAC__uint32 buf[4]; + FLAC__uint32 bytes[2]; + FLAC__multibyte internal_buf; + size_t capacity; +} FLAC__MD5Context; + +void FLAC__MD5Init(FLAC__MD5Context *context); +void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *context); + +FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/memory.h b/deps/flac-1.3.2/src/libFLAC/include/private/memory.h new file mode 100644 index 0000000..f103c53 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/memory.h @@ -0,0 +1,58 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__MEMORY_H +#define FLAC__PRIVATE__MEMORY_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> /* for size_t */ + +#include "private/float.h" +#include "FLAC/ordinals.h" /* for FLAC__bool */ + +/* Returns the unaligned address returned by malloc. + * Use free() on this address to deallocate. + */ +void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); +FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); +FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); +FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); +FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer); +#ifndef FLAC__INTEGER_ONLY_LIBRARY +FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); +#endif +void *safe_malloc_mul_2op_p(size_t size1, size_t size2); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/metadata.h b/deps/flac-1.3.2/src/libFLAC/include/private/metadata.h new file mode 100644 index 0000000..161947f --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/metadata.h @@ -0,0 +1,46 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__METADATA_H +#define FLAC__PRIVATE__METADATA_H + +#include "FLAC/metadata.h" + +/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not + * be a consistent state (e.g. PICTURE) or equivalent to the initial + * state after FLAC__metadata_object_new() + */ +void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object); + +void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/ogg_decoder_aspect.h b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_decoder_aspect.h new file mode 100644 index 0000000..218f44e --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_decoder_aspect.h @@ -0,0 +1,80 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__OGG_DECODER_ASPECT_H +#define FLAC__PRIVATE__OGG_DECODER_ASPECT_H + +#include <ogg/ogg.h> + +#include "FLAC/ordinals.h" +#include "FLAC/stream_decoder.h" /* for FLAC__StreamDecoderReadStatus */ + +typedef struct FLAC__OggDecoderAspect { + /* these are storage for values that can be set through the API */ + FLAC__bool use_first_serial_number; + long serial_number; + + /* these are for internal state related to Ogg decoding */ + ogg_stream_state stream_state; + ogg_sync_state sync_state; + unsigned version_major, version_minor; + FLAC__bool need_serial_number; + FLAC__bool end_of_stream; + FLAC__bool have_working_page; /* only if true will the following vars be valid */ + ogg_page working_page; + FLAC__bool have_working_packet; /* only if true will the following vars be valid */ + ogg_packet working_packet; /* as we work through the packet we will move working_packet.packet forward and working_packet.bytes down */ +} FLAC__OggDecoderAspect; + +void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value); +void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect); +FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect); +void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect); +void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect); +void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect); + +typedef enum { + FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK = 0, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR, + FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR +} FLAC__OggDecoderAspectReadStatus; + +typedef FLAC__OggDecoderAspectReadStatus (*FLAC__OggDecoderAspectReadCallbackProxy)(const void *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/ogg_encoder_aspect.h b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_encoder_aspect.h new file mode 100644 index 0000000..f55ef32 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_encoder_aspect.h @@ -0,0 +1,63 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__OGG_ENCODER_ASPECT_H +#define FLAC__PRIVATE__OGG_ENCODER_ASPECT_H + +#include <ogg/ogg.h> + +#include "FLAC/ordinals.h" +#include "FLAC/stream_encoder.h" /* for FLAC__StreamEncoderWriteStatus */ + +typedef struct FLAC__OggEncoderAspect { + /* these are storage for values that can be set through the API */ + long serial_number; + unsigned num_metadata; + + /* these are for internal state related to Ogg encoding */ + ogg_stream_state stream_state; + ogg_page page; + FLAC__bool seen_magic; /* true if we've seen the fLaC magic in the write callback yet */ + FLAC__bool is_first_packet; + FLAC__uint64 samples_written; +} FLAC__OggEncoderAspect; + +void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value); +FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value); +void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect); +FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect); +void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect); + +typedef FLAC__StreamEncoderWriteStatus (*FLAC__OggEncoderAspectWriteCallbackProxy)(const void *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); + +FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data); +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/ogg_helper.h b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_helper.h new file mode 100644 index 0000000..4c1000c --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_helper.h @@ -0,0 +1,44 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__OGG_HELPER_H +#define FLAC__PRIVATE__OGG_HELPER_H + +#include <ogg/ogg.h> +#include "FLAC/stream_encoder.h" /* for FLAC__StreamEncoder */ + +void simple_ogg_page__init(ogg_page *page); +void simple_ogg_page__clear(ogg_page *page); +FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data); +FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/ogg_mapping.h b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_mapping.h new file mode 100644 index 0000000..1fa022d --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/ogg_mapping.h @@ -0,0 +1,64 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__OGG_MAPPING_H +#define FLAC__PRIVATE__OGG_MAPPING_H + +#include "FLAC/ordinals.h" + +/** The length of the packet type field in bytes. */ +#define FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH (1u) + +extern const unsigned FLAC__OGG_MAPPING_PACKET_TYPE_LEN; /* = 8 bits */ + +extern const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; /* = 0x7f */ + +/** The length of the 'FLAC' magic in bytes. */ +#define FLAC__OGG_MAPPING_MAGIC_LENGTH (4u) + +extern const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC; /* = "FLAC" */ + +extern const unsigned FLAC__OGG_MAPPING_VERSION_MAJOR_LEN; /* = 8 bits */ +extern const unsigned FLAC__OGG_MAPPING_VERSION_MINOR_LEN; /* = 8 bits */ + +/** The length of the Ogg FLAC mapping major version number in bytes. */ +#define FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH (1u) + +/** The length of the Ogg FLAC mapping minor version number in bytes. */ +#define FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH (1u) + +extern const unsigned FLAC__OGG_MAPPING_NUM_HEADERS_LEN; /* = 16 bits */ + +/** The length of the #-of-header-packets number bytes. */ +#define FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH (2u) + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/stream_encoder.h b/deps/flac-1.3.2/src/libFLAC/include/private/stream_encoder.h new file mode 100644 index 0000000..ab1721f --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/stream_encoder.h @@ -0,0 +1,67 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__STREAM_ENCODER_H +#define FLAC__PRIVATE__STREAM_ENCODER_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/* + * This is used to avoid overflow with unusual signals in 32-bit + * accumulator in the *precompute_partition_info_sums_* functions. + */ +#define FLAC__MAX_EXTRA_RESIDUAL_BPS 4 + +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +#include "private/cpu.h" +#include "FLAC/format.h" + +#ifdef FLAC__SSE2_SUPPORTED +extern void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); +#endif + +#ifdef FLAC__SSSE3_SUPPORTED +extern void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); +#endif + +#ifdef FLAC__AVX2_SUPPORTED +extern void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); +#endif + +#endif + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/stream_encoder_framing.h b/deps/flac-1.3.2/src/libFLAC/include/private/stream_encoder_framing.h new file mode 100644 index 0000000..f633a9d --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/stream_encoder_framing.h @@ -0,0 +1,46 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H +#define FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H + +#include "FLAC/format.h" +#include "bitwriter.h" + +FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw); +FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw); +FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); +FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); +FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); +FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/private/window.h b/deps/flac-1.3.2/src/libFLAC/include/private/window.h new file mode 100644 index 0000000..bfed774 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/private/window.h @@ -0,0 +1,74 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2006-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PRIVATE__WINDOW_H +#define FLAC__PRIVATE__WINDOW_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "private/float.h" +#include "FLAC/format.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +/* + * FLAC__window_*() + * -------------------------------------------------------------------- + * Calculates window coefficients according to different apodization + * functions. + * + * OUT window[0,L-1] + * IN L (number of points in window) + */ +void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev); /* 0.0 < stddev <= 0.5 */ +void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L); +void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p); +void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); +void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); +void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L); + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/protected/Makefile.am b/deps/flac-1.3.2/src/libFLAC/include/protected/Makefile.am new file mode 100644 index 0000000..d9c6476 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/protected/Makefile.am @@ -0,0 +1,35 @@ +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +noinst_HEADERS = \ + all.h \ + stream_decoder.h \ + stream_encoder.h diff --git a/deps/flac-1.3.2/src/libFLAC/include/protected/Makefile.in b/deps/flac-1.3.2/src/libFLAC/include/protected/Makefile.in new file mode 100644 index 0000000..faff951 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/protected/Makefile.in @@ -0,0 +1,583 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# libFLAC - Free Lossless Audio Codec library +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# 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 the Xiph.org Foundation 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 FOUNDATION 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. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libFLAC/include/protected +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_HEADERS = \ + all.h \ + stream_decoder.h \ + stream_encoder.h + +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 src/libFLAC/include/protected/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libFLAC/include/protected/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 + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 $(HEADERS) +installdirs: +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 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-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f 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: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + 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-man 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 tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/src/libFLAC/include/protected/all.h b/deps/flac-1.3.2/src/libFLAC/include/protected/all.h new file mode 100644 index 0000000..9468bd3 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/protected/all.h @@ -0,0 +1,39 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PROTECTED__ALL_H +#define FLAC__PROTECTED__ALL_H + +#include "stream_decoder.h" +#include "stream_encoder.h" + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/protected/stream_decoder.h b/deps/flac-1.3.2/src/libFLAC/include/protected/stream_decoder.h new file mode 100644 index 0000000..5c31c16 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/protected/stream_decoder.h @@ -0,0 +1,60 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PROTECTED__STREAM_DECODER_H +#define FLAC__PROTECTED__STREAM_DECODER_H + +#include "FLAC/stream_decoder.h" +#if FLAC__HAS_OGG +#include "private/ogg_decoder_aspect.h" +#endif + +typedef struct FLAC__StreamDecoderProtected { + FLAC__StreamDecoderState state; + FLAC__StreamDecoderInitStatus initstate; + unsigned channels; + FLAC__ChannelAssignment channel_assignment; + unsigned bits_per_sample; + unsigned sample_rate; /* in Hz */ + unsigned blocksize; /* in samples (per channel) */ + FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */ +#if FLAC__HAS_OGG + FLAC__OggDecoderAspect ogg_decoder_aspect; +#endif +} FLAC__StreamDecoderProtected; + +/* + * return the number of input bytes consumed + */ +unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder); + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/include/protected/stream_encoder.h b/deps/flac-1.3.2/src/libFLAC/include/protected/stream_encoder.h new file mode 100644 index 0000000..8850c6b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/include/protected/stream_encoder.h @@ -0,0 +1,118 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifndef FLAC__PROTECTED__STREAM_ENCODER_H +#define FLAC__PROTECTED__STREAM_ENCODER_H + +#include "FLAC/stream_encoder.h" +#if FLAC__HAS_OGG +#include "private/ogg_encoder_aspect.h" +#endif + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +#include "private/float.h" + +#define FLAC__MAX_APODIZATION_FUNCTIONS 32 + +typedef enum { + FLAC__APODIZATION_BARTLETT, + FLAC__APODIZATION_BARTLETT_HANN, + FLAC__APODIZATION_BLACKMAN, + FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE, + FLAC__APODIZATION_CONNES, + FLAC__APODIZATION_FLATTOP, + FLAC__APODIZATION_GAUSS, + FLAC__APODIZATION_HAMMING, + FLAC__APODIZATION_HANN, + FLAC__APODIZATION_KAISER_BESSEL, + FLAC__APODIZATION_NUTTALL, + FLAC__APODIZATION_RECTANGLE, + FLAC__APODIZATION_TRIANGLE, + FLAC__APODIZATION_TUKEY, + FLAC__APODIZATION_PARTIAL_TUKEY, + FLAC__APODIZATION_PUNCHOUT_TUKEY, + FLAC__APODIZATION_WELCH +} FLAC__ApodizationFunction; + +typedef struct { + FLAC__ApodizationFunction type; + union { + struct { + FLAC__real stddev; + } gauss; + struct { + FLAC__real p; + } tukey; + struct { + FLAC__real p; + FLAC__real start; + FLAC__real end; + } multiple_tukey; + } parameters; +} FLAC__ApodizationSpecification; + +#endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY + +typedef struct FLAC__StreamEncoderProtected { + FLAC__StreamEncoderState state; + FLAC__bool verify; + FLAC__bool streamable_subset; + FLAC__bool do_md5; + FLAC__bool do_mid_side_stereo; + FLAC__bool loose_mid_side_stereo; + unsigned channels; + unsigned bits_per_sample; + unsigned sample_rate; + unsigned blocksize; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + unsigned num_apodizations; + FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS]; +#endif + unsigned max_lpc_order; + unsigned qlp_coeff_precision; + FLAC__bool do_qlp_coeff_prec_search; + FLAC__bool do_exhaustive_model_search; + FLAC__bool do_escape_coding; + unsigned min_residual_partition_order; + unsigned max_residual_partition_order; + unsigned rice_parameter_search_dist; + FLAC__uint64 total_samples_estimate; + FLAC__StreamMetadata **metadata; + unsigned num_metadata_blocks; + FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; +#if FLAC__HAS_OGG + FLAC__OggEncoderAspect ogg_encoder_aspect; +#endif +} FLAC__StreamEncoderProtected; + +#endif diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC.m4 b/deps/flac-1.3.2/src/libFLAC/libFLAC.m4 new file mode 100644 index 0000000..da7354e --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC.m4 @@ -0,0 +1,118 @@ +# Configure paths for libFLAC +# "Inspired" by ogg.m4 + +dnl AM_PATH_LIBFLAC([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for libFLAC, and define LIBFLAC_CFLAGS, LIBFLAC_LIBS, LIBFLAC_LIBDIR +dnl +AC_DEFUN([AM_PATH_LIBFLAC], +[dnl +dnl Get the cflags and libraries +dnl +AC_ARG_WITH(libFLAC,[ --with-libFLAC=PFX Prefix where libFLAC is installed (optional)], libFLAC_prefix="$withval", libFLAC_prefix="") +AC_ARG_WITH(libFLAC-libraries,[ --with-libFLAC-libraries=DIR Directory where libFLAC library is installed (optional)], libFLAC_libraries="$withval", libFLAC_libraries="") +AC_ARG_WITH(libFLAC-includes,[ --with-libFLAC-includes=DIR Directory where libFLAC header files are installed (optional)], libFLAC_includes="$withval", libFLAC_includes="") +AC_ARG_ENABLE(libFLACtest, [ --disable-libFLACtest Do not try to compile and run a test libFLAC program],, enable_libFLACtest=yes) + + if test "x$libFLAC_libraries" != "x" ; then + LIBFLAC_LIBS="-L$libFLAC_libraries" + elif test "x$libFLAC_prefix" = "xno" || test "x$libFLAC_prefix" = "xyes" ; then + LIBFLAC_LIBS="" + elif test "x$libFLAC_prefix" != "x" ; then + LIBFLAC_LIBS="-L$libFLAC_prefix/lib" + elif test "x$prefix" != "xNONE"; then + LIBFLAC_LIBS="-L$prefix/lib" + fi + + if test "x$libFLAC_prefix" != "xno" ; then + LIBFLAC_LIBS="$LIBFLAC_LIBS -lFLAC $OGG_LIBS -lm" + fi + + if test "x$libFLAC_includes" != "x" ; then + LIBFLAC_CFLAGS="-I$libFLAC_includes" + elif test "x$libFLAC_prefix" != "x" ; then + LIBFLAC_CFLAGS="-I$libFLAC_prefix/include" + elif test "$prefix" != "xNONE"; then + LIBFLAC_CFLAGS="" + fi + + AC_MSG_CHECKING(for libFLAC) + no_libFLAC="" + + + if test "x$enable_libFLACtest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + ac_save_LD_LIBRARY_PATH="$LD_LIBRARY_PATH" + CFLAGS="$CFLAGS $LIBFLAC_CFLAGS" + CXXFLAGS="$CXXFLAGS $LIBFLAC_CFLAGS" + LIBS="$LIBS $LIBFLAC_LIBS" + LD_LIBRARY_PATH="$LIBFLAC_LIBDIR:$LD_LIBRARY_PATH" +dnl +dnl Now check if the installed libFLAC is sufficiently new. +dnl + rm -f conf.libFLACtest + AC_TRY_RUN([ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <FLAC/format.h> + +int main () +{ + system("touch conf.libFLACtest"); + return 0; +} + +],, no_libFLAC=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + LD_LIBRARY_PATH="$ac_save_LD_LIBRARY_PATH" + fi + + if test "x$no_libFLAC" = "x" ; then + AC_MSG_RESULT(yes) + ifelse([$1], , :, [$1]) + else + AC_MSG_RESULT(no) + if test -f conf.libFLACtest ; then + : + else + echo "*** Could not run libFLAC test program, checking why..." + CFLAGS="$CFLAGS $LIBFLAC_CFLAGS" + CXXFLAGS="$CXXFLAGS $LIBFLAC_CFLAGS" + LIBS="$LIBS $LIBFLAC_LIBS" + LD_LIBRARY_PATH="$LIBFLAC_LIBDIR:$LD_LIBRARY_PATH" + AC_TRY_LINK([ +#include <stdio.h> +#include <FLAC/format.h> +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding libFLAC or finding the wrong" + echo "*** version of libFLAC. If it is not finding libFLAC, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means libFLAC was incorrectly installed" + echo "*** or that you have moved libFLAC since it was installed. In the latter case, you" + echo "*** may want to edit the libFLAC-config script: $LIBFLAC_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + LD_LIBRARY_PATH="$ac_save_LD_LIBRARY_PATH" + fi + LIBFLAC_CFLAGS="" + LIBFLAC_LIBDIR="" + LIBFLAC_LIBS="" + ifelse([$2], , :, [$2]) + fi + AC_SUBST(LIBFLAC_CFLAGS) + AC_SUBST(LIBFLAC_LIBDIR) + AC_SUBST(LIBFLAC_LIBS) + rm -f conf.libFLACtest +]) diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcproj b/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcproj new file mode 100644 index 0000000..52e12c0 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcproj @@ -0,0 +1,550 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libFLAC_dynamic"
+ ProjectGUID="{4cefbc83-c215-11db-8314-0800200c9a66}"
+ RootNamespace="libFLAC_dynamic"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)_dynamic"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/D "_USE_MATH_DEFINES""
+ Optimization="0"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=".\include;..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION=\"1.3.2\";DEBUG;FLAC__OVERFLOW_DETECT"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(SolutionDir)objs\$(ConfigurationName)\lib\libogg_static.lib"
+ LinkIncremental="2"
+ IgnoreDefaultLibraryNames="uuid.lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)_dynamic"
+ ConfigurationType="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/D "_USE_MATH_DEFINES""
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION=\"1.3.2\";FLaC__INLINE=_inline"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(SolutionDir)objs\$(ConfigurationName)\lib\libogg_static.lib"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames="uuid.lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\include\protected\all.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\all.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\bitmath.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\bitreader.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\bitwriter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\cpu.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\crc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\fixed.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\float.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\format.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\lpc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\md5.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\memory.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\metadata.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ia32\nasm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_decoder_aspect.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_encoder_aspect.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_mapping.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\protected\stream_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\stream_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\protected\stream_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\stream_encoder_framing.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\window.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\bitmath.c"
+ >
+ </File>
+ <File
+ RelativePath=".\bitreader.c"
+ >
+ </File>
+ <File
+ RelativePath=".\bitwriter.c"
+ >
+ </File>
+ <File
+ RelativePath=".\cpu.c"
+ >
+ </File>
+ <File
+ RelativePath=".\crc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\fixed.c"
+ >
+ </File>
+ <File
+ RelativePath=".\fixed_intrin_sse2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\fixed_intrin_ssse3.c"
+ >
+ </File>
+ <File
+ RelativePath=".\float.c"
+ >
+ </File>
+ <File
+ RelativePath=".\format.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc_intrin_sse.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc_intrin_sse2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc_intrin_sse41.c"
+ >
+ </File>
+ <File
+ RelativePath=".\md5.c"
+ >
+ </File>
+ <File
+ RelativePath=".\memory.c"
+ >
+ </File>
+ <File
+ RelativePath=".\metadata_iterators.c"
+ >
+ </File>
+ <File
+ RelativePath=".\metadata_object.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_decoder_aspect.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_encoder_aspect.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_helper.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_mapping.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_decoder.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder_framing.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder_intrin_sse2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder_intrin_ssse3.c"
+ >
+ </File>
+ <File
+ RelativePath=".\window.c"
+ >
+ </File>
+ <File
+ RelativePath=".\windows_unicode_filenames.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\include\FLAC\all.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\alloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\assert.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\callback.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\compat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\endswap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\export.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\format.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\macros.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\metadata.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\ordinals.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\private.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\safe_str.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\stream_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\stream_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\windows_unicode_filenames.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ia32\cpu_asm.nasm"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
"
+ AdditionalDependencies="ia32/cpu_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/cpu_asm.obj"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
"
+ AdditionalDependencies="ia32/cpu_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/cpu_asm.obj"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ia32\fixed_asm.nasm"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
"
+ AdditionalDependencies="ia32/fixed_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/fixed_asm.obj"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
"
+ AdditionalDependencies="ia32/fixed_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/fixed_asm.obj"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ia32\lpc_asm.nasm"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
"
+ AdditionalDependencies="ia32/lpc_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/lpc_asm.obj"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
"
+ AdditionalDependencies="ia32/lpc_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/lpc_asm.obj"
+ />
+ </FileConfiguration>
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcxproj b/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcxproj new file mode 100644 index 0000000..b907a62 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcxproj @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc83-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>libFLAC_dynamic</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ <IntDir>$(Configuration)_dynamic\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)_dynamic\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ <IntDir>$(Configuration)_dynamic\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)_dynamic\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";DEBUG;FLAC__OVERFLOW_DETECT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>$(SolutionDir)objs\$(Configuration)\lib\libogg_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;ENABLE_64_BIT_WORDS;FLAC__CPU_X86_64;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";DEBUG;FLAC__OVERFLOW_DETECT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\libogg_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";FLaC__INLINE=_inline;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>$(SolutionDir)objs\$(Configuration)\lib\libogg_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;ENABLE_64_BIT_WORDS;FLAC__CPU_X86_64;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";FLaC__INLINE=_inline;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\libogg_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\FLAC\all.h" />
+ <ClInclude Include="..\..\include\FLAC\assert.h" />
+ <ClInclude Include="..\..\include\FLAC\callback.h" />
+ <ClInclude Include="..\..\include\FLAC\export.h" />
+ <ClInclude Include="..\..\include\FLAC\format.h" />
+ <ClInclude Include="..\..\include\FLAC\metadata.h" />
+ <ClInclude Include="..\..\include\FLAC\ordinals.h" />
+ <ClInclude Include="..\..\include\FLAC\stream_decoder.h" />
+ <ClInclude Include="..\..\include\FLAC\stream_encoder.h" />
+ <ClInclude Include="..\..\include\share\alloc.h" />
+ <ClInclude Include="..\..\include\share\compat.h" />
+ <ClInclude Include="..\..\include\share\endswap.h" />
+ <ClInclude Include="..\..\include\share\macros.h" />
+ <ClInclude Include="..\..\include\share\private.h" />
+ <ClInclude Include="..\..\include\share\safe_str.h" />
+ <ClInclude Include="..\..\include\share\windows_unicode_filenames.h" />
+ <ClInclude Include="ia32\nasm.h" />
+ <ClInclude Include="include\private\all.h" />
+ <ClInclude Include="include\private\bitmath.h" />
+ <ClInclude Include="include\private\bitreader.h" />
+ <ClInclude Include="include\private\bitwriter.h" />
+ <ClInclude Include="include\private\cpu.h" />
+ <ClInclude Include="include\private\crc.h" />
+ <ClInclude Include="include\private\fixed.h" />
+ <ClInclude Include="include\private\float.h" />
+ <ClInclude Include="include\private\format.h" />
+ <ClInclude Include="include\private\lpc.h" />
+ <ClInclude Include="include\private\md5.h" />
+ <ClInclude Include="include\private\memory.h" />
+ <ClInclude Include="include\private\metadata.h" />
+ <ClInclude Include="include\private\ogg_decoder_aspect.h" />
+ <ClInclude Include="include\private\ogg_encoder_aspect.h" />
+ <ClInclude Include="include\private\ogg_helper.h" />
+ <ClInclude Include="include\private\ogg_mapping.h" />
+ <ClInclude Include="include\private\stream_encoder.h" />
+ <ClInclude Include="include\private\stream_encoder_framing.h" />
+ <ClInclude Include="include\private\window.h" />
+ <ClInclude Include="include\protected\all.h" />
+ <ClInclude Include="include\protected\stream_decoder.h" />
+ <ClInclude Include="include\protected\stream_encoder.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="bitmath.c" />
+ <ClCompile Include="bitreader.c" />
+ <ClCompile Include="bitwriter.c" />
+ <ClCompile Include="cpu.c" />
+ <ClCompile Include="crc.c" />
+ <ClCompile Include="fixed.c" />
+ <ClCompile Include="fixed_intrin_sse2.c" />
+ <ClCompile Include="fixed_intrin_ssse3.c" />
+ <ClCompile Include="float.c" />
+ <ClCompile Include="format.c" />
+ <ClCompile Include="lpc.c" />
+ <ClCompile Include="lpc_intrin_avx2.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse.c" />
+ <ClCompile Include="lpc_intrin_sse2.c" />
+ <ClCompile Include="lpc_intrin_sse41.c" />
+ <ClCompile Include="md5.c" />
+ <ClCompile Include="memory.c" />
+ <ClCompile Include="metadata_iterators.c" />
+ <ClCompile Include="metadata_object.c" />
+ <ClCompile Include="ogg_decoder_aspect.c" />
+ <ClCompile Include="ogg_encoder_aspect.c" />
+ <ClCompile Include="ogg_helper.c" />
+ <ClCompile Include="ogg_mapping.c" />
+ <ClCompile Include="stream_decoder.c" />
+ <ClCompile Include="stream_encoder.c" />
+ <ClCompile Include="stream_encoder_framing.c" />
+ <ClCompile Include="stream_encoder_intrin_avx2.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_sse2.c" />
+ <ClCompile Include="stream_encoder_intrin_ssse3.c" />
+ <ClCompile Include="window.c" />
+ <ClCompile Include="windows_unicode_filenames.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="ia32\cpu_asm.nasm">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <CustomBuild Include="ia32\fixed_asm.nasm">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <CustomBuild Include="ia32\lpc_asm.nasm">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcxproj.filters b/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcxproj.filters new file mode 100644 index 0000000..875c021 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC_dynamic.vcxproj.filters @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{c048646d-1833-4a52-9849-022db831cc79}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="include\private\all.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\protected\all.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\bitmath.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\bitreader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\bitwriter.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\cpu.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\crc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\fixed.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\float.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\format.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\lpc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\md5.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\memory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\metadata.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ia32\nasm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_decoder_aspect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_encoder_aspect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_helper.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_mapping.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\protected\stream_decoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\protected\stream_encoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\stream_encoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\stream_encoder_framing.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\window.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\all.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\assert.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\callback.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\export.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\format.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\metadata.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\ordinals.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\stream_decoder.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\stream_encoder.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\alloc.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\compat.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\endswap.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\macros.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\private.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\safe_str.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\windows_unicode_filenames.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="bitmath.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="bitreader.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="bitwriter.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="cpu.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="crc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fixed.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fixed_intrin_sse2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fixed_intrin_ssse3.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="float.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="format.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse41.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_avx2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="md5.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="memory.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="metadata_iterators.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="metadata_object.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_decoder_aspect.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_encoder_aspect.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_helper.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_mapping.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_decoder.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_framing.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_sse2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_ssse3.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_avx2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="window.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="windows_unicode_filenames.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="ia32\cpu_asm.nasm" />
+ <CustomBuild Include="ia32\fixed_asm.nasm" />
+ <CustomBuild Include="ia32\lpc_asm.nasm" />
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcproj b/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcproj new file mode 100644 index 0000000..5bff5d8 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcproj @@ -0,0 +1,523 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libFLAC_static"
+ ProjectGUID="{4cefbc84-c215-11db-8314-0800200c9a66}"
+ RootNamespace="libFLAC_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/D "_USE_MATH_DEFINES""
+ Optimization="0"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=".\include;..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION=\"1.3.2\";FLAC__NO_DLL;DEBUG;FLAC__OVERFLOW_DETECT"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/D "_USE_MATH_DEFINES""
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION=\"1.3.2\";FLAC__NO_DLL;FLaC__INLINE=_inline"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\include\private\all.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\protected\all.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\bitmath.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\bitreader.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\bitwriter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\cpu.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\crc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\fixed.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\float.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\format.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\lpc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\md5.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\memory.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\metadata.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ia32\nasm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_decoder_aspect.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_encoder_aspect.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_helper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\ogg_mapping.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\protected\stream_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\stream_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\protected\stream_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\stream_encoder_framing.h"
+ >
+ </File>
+ <File
+ RelativePath=".\include\private\window.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\include\FLAC\all.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\alloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\assert.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\callback.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\compat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\endswap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\export.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\format.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\macros.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\metadata.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\ordinals.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\private.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\safe_str.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\stream_decoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\FLAC\stream_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\share\windows_unicode_filenames.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\bitmath.c"
+ >
+ </File>
+ <File
+ RelativePath=".\bitreader.c"
+ >
+ </File>
+ <File
+ RelativePath=".\bitwriter.c"
+ >
+ </File>
+ <File
+ RelativePath=".\cpu.c"
+ >
+ </File>
+ <File
+ RelativePath=".\crc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\fixed.c"
+ >
+ </File>
+ <File
+ RelativePath=".\fixed_intrin_sse2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\fixed_intrin_ssse3.c"
+ >
+ </File>
+ <File
+ RelativePath=".\float.c"
+ >
+ </File>
+ <File
+ RelativePath=".\format.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc_intrin_sse.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc_intrin_sse2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lpc_intrin_sse41.c"
+ >
+ </File>
+ <File
+ RelativePath=".\md5.c"
+ >
+ </File>
+ <File
+ RelativePath=".\memory.c"
+ >
+ </File>
+ <File
+ RelativePath=".\metadata_iterators.c"
+ >
+ </File>
+ <File
+ RelativePath=".\metadata_object.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_decoder_aspect.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_encoder_aspect.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_helper.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ogg_mapping.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_decoder.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder_framing.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder_intrin_sse2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\stream_encoder_intrin_ssse3.c"
+ >
+ </File>
+ <File
+ RelativePath=".\window.c"
+ >
+ </File>
+ <File
+ RelativePath=".\windows_unicode_filenames.c"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ia32\cpu_asm.nasm"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
"
+ AdditionalDependencies="ia32/cpu_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/cpu_asm.obj"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
"
+ AdditionalDependencies="ia32/cpu_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/cpu_asm.obj"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ia32\fixed_asm.nasm"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
"
+ AdditionalDependencies="ia32/fixed_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/fixed_asm.obj"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
"
+ AdditionalDependencies="ia32/fixed_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/fixed_asm.obj"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\ia32\lpc_asm.nasm"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
"
+ AdditionalDependencies="ia32/lpc_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/lpc_asm.obj"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
"
+ AdditionalDependencies="ia32/lpc_asm.nasm;ia32/nasm.h"
+ Outputs="ia32/lpc_asm.obj"
+ />
+ </FileConfiguration>
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcxproj b/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcxproj new file mode 100644 index 0000000..599faed --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcxproj @@ -0,0 +1,287 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc84-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>libFLAC_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";FLAC__NO_DLL;DEBUG;FLAC__OVERFLOW_DETECT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__HAS_OGG;ENABLE_64_BIT_WORDS;FLAC__CPU_X86_64;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";FLAC__NO_DLL;DEBUG;FLAC__OVERFLOW_DETECT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";FLAC__NO_DLL;FLaC__INLINE=_inline;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions>/D "_USE_MATH_DEFINES" %(AdditionalOptions)</AdditionalOptions>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__HAS_OGG;ENABLE_64_BIT_WORDS;FLAC__CPU_X86_64;FLAC__HAS_X86INTRIN;FLAC__ALIGN_MALLOC_DATA;PACKAGE_VERSION="1.3.2";FLAC__NO_DLL;FLaC__INLINE=_inline;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\FLAC\all.h" />
+ <ClInclude Include="..\..\include\FLAC\assert.h" />
+ <ClInclude Include="..\..\include\FLAC\callback.h" />
+ <ClInclude Include="..\..\include\FLAC\export.h" />
+ <ClInclude Include="..\..\include\FLAC\format.h" />
+ <ClInclude Include="..\..\include\FLAC\metadata.h" />
+ <ClInclude Include="..\..\include\FLAC\ordinals.h" />
+ <ClInclude Include="..\..\include\FLAC\stream_decoder.h" />
+ <ClInclude Include="..\..\include\FLAC\stream_encoder.h" />
+ <ClInclude Include="..\..\include\share\alloc.h" />
+ <ClInclude Include="..\..\include\share\compat.h" />
+ <ClInclude Include="..\..\include\share\endswap.h" />
+ <ClInclude Include="..\..\include\share\macros.h" />
+ <ClInclude Include="..\..\include\share\private.h" />
+ <ClInclude Include="..\..\include\share\safe_str.h" />
+ <ClInclude Include="..\..\include\share\windows_unicode_filenames.h" />
+ <ClInclude Include="ia32\nasm.h" />
+ <ClInclude Include="include\private\all.h" />
+ <ClInclude Include="include\private\bitmath.h" />
+ <ClInclude Include="include\private\bitreader.h" />
+ <ClInclude Include="include\private\bitwriter.h" />
+ <ClInclude Include="include\private\cpu.h" />
+ <ClInclude Include="include\private\crc.h" />
+ <ClInclude Include="include\private\fixed.h" />
+ <ClInclude Include="include\private\float.h" />
+ <ClInclude Include="include\private\format.h" />
+ <ClInclude Include="include\private\lpc.h" />
+ <ClInclude Include="include\private\md5.h" />
+ <ClInclude Include="include\private\memory.h" />
+ <ClInclude Include="include\private\metadata.h" />
+ <ClInclude Include="include\private\ogg_decoder_aspect.h" />
+ <ClInclude Include="include\private\ogg_encoder_aspect.h" />
+ <ClInclude Include="include\private\ogg_helper.h" />
+ <ClInclude Include="include\private\ogg_mapping.h" />
+ <ClInclude Include="include\private\stream_encoder.h" />
+ <ClInclude Include="include\private\stream_encoder_framing.h" />
+ <ClInclude Include="include\private\window.h" />
+ <ClInclude Include="include\protected\all.h" />
+ <ClInclude Include="include\protected\stream_decoder.h" />
+ <ClInclude Include="include\protected\stream_encoder.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="bitmath.c" />
+ <ClCompile Include="bitreader.c" />
+ <ClCompile Include="bitwriter.c" />
+ <ClCompile Include="cpu.c" />
+ <ClCompile Include="crc.c" />
+ <ClCompile Include="fixed.c" />
+ <ClCompile Include="fixed_intrin_sse2.c" />
+ <ClCompile Include="fixed_intrin_ssse3.c" />
+ <ClCompile Include="float.c" />
+ <ClCompile Include="format.c" />
+ <ClCompile Include="lpc.c" />
+ <ClCompile Include="lpc_intrin_avx2.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse.c" />
+ <ClCompile Include="lpc_intrin_sse2.c" />
+ <ClCompile Include="lpc_intrin_sse41.c" />
+ <ClCompile Include="md5.c" />
+ <ClCompile Include="memory.c" />
+ <ClCompile Include="metadata_iterators.c" />
+ <ClCompile Include="metadata_object.c" />
+ <ClCompile Include="ogg_decoder_aspect.c" />
+ <ClCompile Include="ogg_encoder_aspect.c" />
+ <ClCompile Include="ogg_helper.c" />
+ <ClCompile Include="ogg_mapping.c" />
+ <ClCompile Include="stream_decoder.c" />
+ <ClCompile Include="stream_encoder.c" />
+ <ClCompile Include="stream_encoder_framing.c" />
+ <ClCompile Include="stream_encoder_intrin_avx2.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/arch:AVX %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_sse2.c" />
+ <ClCompile Include="stream_encoder_intrin_ssse3.c" />
+ <ClCompile Include="window.c" />
+ <ClCompile Include="windows_unicode_filenames.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="ia32\cpu_asm.nasm">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/cpu_asm.nasm -o ia32/cpu_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/cpu_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/cpu_asm.obj;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <CustomBuild Include="ia32\fixed_asm.nasm">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/fixed_asm.nasm -o ia32/fixed_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/fixed_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/fixed_asm.obj;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <CustomBuild Include="ia32\lpc_asm.nasm">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm.exe -f win32 -d OBJ_FORMAT_win32 -i ia32/ ia32/lpc_asm.nasm -o ia32/lpc_asm.obj
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/lpc_asm.nasm;ia32/nasm.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ia32/lpc_asm.obj;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcxproj.filters b/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcxproj.filters new file mode 100644 index 0000000..a600678 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/libFLAC_static.vcxproj.filters @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{7493d9cf-1406-4a3c-9811-63f0cd6ccd36}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="include\protected\all.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\all.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\bitmath.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\bitreader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\bitwriter.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\cpu.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\crc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\fixed.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\float.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\format.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\lpc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\md5.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\memory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\metadata.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ia32\nasm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_decoder_aspect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_encoder_aspect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_helper.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\ogg_mapping.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\protected\stream_decoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\protected\stream_encoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\stream_encoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\stream_encoder_framing.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\private\window.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\all.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\assert.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\callback.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\export.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\format.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\metadata.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\ordinals.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\stream_decoder.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\FLAC\stream_encoder.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\alloc.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\compat.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\endswap.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\macros.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\private.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\safe_str.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\share\windows_unicode_filenames.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="bitmath.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="bitreader.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="bitwriter.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="cpu.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="crc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fixed.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fixed_intrin_sse2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fixed_intrin_ssse3.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="float.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="format.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_sse41.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lpc_intrin_avx2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="md5.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="memory.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="metadata_iterators.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="metadata_object.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_decoder_aspect.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_encoder_aspect.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_helper.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ogg_mapping.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_decoder.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_framing.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_sse2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_ssse3.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stream_encoder_intrin_avx2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="window.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="windows_unicode_filenames.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="ia32\cpu_asm.nasm" />
+ <CustomBuild Include="ia32\fixed_asm.nasm" />
+ <CustomBuild Include="ia32\lpc_asm.nasm" />
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/libFLAC/lpc.c b/deps/flac-1.3.2/src/libFLAC/lpc.c new file mode 100644 index 0000000..531247b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/lpc.c @@ -0,0 +1,1357 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <math.h> + +#include "FLAC/assert.h" +#include "FLAC/format.h" +#include "share/compat.h" +#include "private/bitmath.h" +#include "private/lpc.h" +#include "private/macros.h" +#if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE +#include <stdio.h> +#endif + +/* OPT: #undef'ing this may improve the speed on some architectures */ +#define FLAC__LPC_UNROLLED_FILTER_LOOPS + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +#if defined(_MSC_VER) && (_MSC_VER < 1800) +#include <float.h> +static inline long int lround(double x) { + return (long)(x + _copysign(0.5, x)); +} +#elif !defined(HAVE_LROUND) && defined(__GNUC__) +static inline long int lround(double x) { + return (long)(x + __builtin_copysign(0.5, x)); +} +/* If this fails, we are in the presence of a mid 90's compiler, move along... */ +#endif + +void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) +{ + unsigned i; + for(i = 0; i < data_len; i++) + out[i] = in[i] * window[i]; +} + +void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + /* a readable, but slower, version */ +#if 0 + FLAC__real d; + unsigned i; + + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= data_len); + + /* + * Technically we should subtract the mean first like so: + * for(i = 0; i < data_len; i++) + * data[i] -= mean; + * but it appears not to make enough of a difference to matter, and + * most signals are already closely centered around zero + */ + while(lag--) { + for(i = lag, d = 0.0; i < data_len; i++) + d += data[i] * data[i - lag]; + autoc[lag] = d; + } +#endif + + /* + * this version tends to run faster because of better data locality + * ('data_len' is usually much larger than 'lag') + */ + FLAC__real d; + unsigned sample, coeff; + const unsigned limit = data_len - lag; + + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= data_len); + + for(coeff = 0; coeff < lag; coeff++) + autoc[coeff] = 0.0; + for(sample = 0; sample <= limit; sample++) { + d = data[sample]; + for(coeff = 0; coeff < lag; coeff++) + autoc[coeff] += d * data[sample+coeff]; + } + for(; sample < data_len; sample++) { + d = data[sample]; + for(coeff = 0; coeff < data_len - sample; coeff++) + autoc[coeff] += d * data[sample+coeff]; + } +} + +void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]) +{ + unsigned i, j; + double r, err, lpc[FLAC__MAX_LPC_ORDER]; + + FLAC__ASSERT(0 != max_order); + FLAC__ASSERT(0 < *max_order); + FLAC__ASSERT(*max_order <= FLAC__MAX_LPC_ORDER); + FLAC__ASSERT(autoc[0] != 0.0); + + err = autoc[0]; + + for(i = 0; i < *max_order; i++) { + /* Sum up this iteration's reflection coefficient. */ + r = -autoc[i+1]; + for(j = 0; j < i; j++) + r -= lpc[j] * autoc[i-j]; + r /= err; + + /* Update LPC coefficients and total error. */ + lpc[i]=r; + for(j = 0; j < (i>>1); j++) { + double tmp = lpc[j]; + lpc[j] += r * lpc[i-1-j]; + lpc[i-1-j] += r * tmp; + } + if(i & 1) + lpc[j] += lpc[j] * r; + + err *= (1.0 - r * r); + + /* save this order */ + for(j = 0; j <= i; j++) + lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ + error[i] = err; + + /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */ + if(err == 0.0) { + *max_order = i+1; + return; + } + } +} + +int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift) +{ + unsigned i; + double cmax; + FLAC__int32 qmax, qmin; + + FLAC__ASSERT(precision > 0); + FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION); + + /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */ + precision--; + qmax = 1 << precision; + qmin = -qmax; + qmax--; + + /* calc cmax = max( |lp_coeff[i]| ) */ + cmax = 0.0; + for(i = 0; i < order; i++) { + const double d = fabs(lp_coeff[i]); + if(d > cmax) + cmax = d; + } + + if(cmax <= 0.0) { + /* => coefficients are all 0, which means our constant-detect didn't work */ + return 2; + } + else { + const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1; + const int min_shiftlimit = -max_shiftlimit - 1; + int log2cmax; + + (void)frexp(cmax, &log2cmax); + log2cmax--; + *shift = (int)precision - log2cmax - 1; + + if(*shift > max_shiftlimit) + *shift = max_shiftlimit; + else if(*shift < min_shiftlimit) + return 1; + } + + if(*shift >= 0) { + double error = 0.0; + FLAC__int32 q; + for(i = 0; i < order; i++) { + error += lp_coeff[i] * (1 << *shift); + q = lround(error); + +#ifdef FLAC__OVERFLOW_DETECT + if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ + fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); + else if(q < qmin) + fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmin,*shift,cmax,precision+1,i,lp_coeff[i]); +#endif + if(q > qmax) + q = qmax; + else if(q < qmin) + q = qmin; + error -= q; + qlp_coeff[i] = q; + } + } + /* negative shift is very rare but due to design flaw, negative shift is + * not allowed in the decoder, so it must be handled specially by scaling + * down coeffs + */ + else { + const int nshift = -(*shift); + double error = 0.0; + FLAC__int32 q; +#ifdef DEBUG + fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f\n", *shift, order, cmax); +#endif + for(i = 0; i < order; i++) { + error += lp_coeff[i] / (1 << nshift); + q = lround(error); +#ifdef FLAC__OVERFLOW_DETECT + if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ + fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); + else if(q < qmin) + fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmin,*shift,cmax,precision+1,i,lp_coeff[i]); +#endif + if(q > qmax) + q = qmax; + else if(q < qmin) + q = qmin; + error -= q; + qlp_coeff[i] = q; + } + *shift = 0; + } + + return 0; +} + +#if defined(_MSC_VER) +// silence MSVC warnings about __restrict modifier +#pragma warning ( disable : 4028 ) +#endif + +void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual) +#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) +{ + FLAC__int64 sumo; + unsigned i, j; + FLAC__int32 sum; + const FLAC__int32 *history; + +#ifdef FLAC__OVERFLOW_DETECT_VERBOSE + fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); + for(i=0;i<order;i++) + fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); + fprintf(stderr,"\n"); +#endif + FLAC__ASSERT(order > 0); + + for(i = 0; i < data_len; i++) { + sumo = 0; + sum = 0; + history = data; + for(j = 0; j < order; j++) { + sum += qlp_coeff[j] * (*(--history)); + sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); + if(sumo > 2147483647ll || sumo < -2147483648ll) + fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); + } + *(residual++) = *(data++) - (sum >> lp_quantization); + } + + /* Here's a slower but clearer version: + for(i = 0; i < data_len; i++) { + sum = 0; + for(j = 0; j < order; j++) + sum += qlp_coeff[j] * data[i-j-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + */ +} +#else /* fully unrolled version for normal use */ +{ + int i; + FLAC__int32 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + * We do unique versions up to 12th order since that's the subset limit. + * Also they are roughly ordered to match frequency of occurrence to + * minimize branching. + */ + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[9] * data[i-10]; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order == 11 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[9] * data[i-10]; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + else { + if(order == 10) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * data[i-10]; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order == 9 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order == 7 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + else { + if(order == 6) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order == 5 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order == 3 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + else { + if(order == 2) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order == 1 */ + for(i = 0; i < (int)data_len; i++) + residual[i] = data[i] - ((qlp_coeff[0] * data[i-1]) >> lp_quantization); + } + } + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } +} +#endif + +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual) +#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) +{ + unsigned i, j; + FLAC__int64 sum; + const FLAC__int32 *history; + +#ifdef FLAC__OVERFLOW_DETECT_VERBOSE + fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); + for(i=0;i<order;i++) + fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); + fprintf(stderr,"\n"); +#endif + FLAC__ASSERT(order > 0); + + for(i = 0; i < data_len; i++) { + sum = 0; + history = data; + for(j = 0; j < order; j++) + sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); + if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { + fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); + break; + } + if(FLAC__bitmath_silog2((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { + fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (int64_t)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization))); + break; + } + *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); + } +} +#else /* fully unrolled version for normal use */ +{ + int i; + FLAC__int64 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + * We do unique versions up to 12th order since that's the subset limit. + * Also they are roughly ordered to match frequency of occurrence to + * minimize branching. + */ + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 11 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + else { + if(order == 10) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 9 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 7 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + else { + if(order == 6) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 5 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 3 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + else { + if(order == 2) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 1 */ + for(i = 0; i < (int)data_len; i++) + residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); + } + } + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } +} +#endif + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + +void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data) +#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) +{ + FLAC__int64 sumo; + unsigned i, j; + FLAC__int32 sum; + const FLAC__int32 *r = residual, *history; + +#ifdef FLAC__OVERFLOW_DETECT_VERBOSE + fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); + for(i=0;i<order;i++) + fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); + fprintf(stderr,"\n"); +#endif + FLAC__ASSERT(order > 0); + + for(i = 0; i < data_len; i++) { + sumo = 0; + sum = 0; + history = data; + for(j = 0; j < order; j++) { + sum += qlp_coeff[j] * (*(--history)); + sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); + if(sumo > 2147483647ll || sumo < -2147483648ll) + fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); + } + *(data++) = *(r++) + (sum >> lp_quantization); + } + + /* Here's a slower but clearer version: + for(i = 0; i < data_len; i++) { + sum = 0; + for(j = 0; j < order; j++) + sum += qlp_coeff[j] * data[i-j-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + */ +} +#else /* fully unrolled version for normal use */ +{ + int i; + FLAC__int32 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + * We do unique versions up to 12th order since that's the subset limit. + * Also they are roughly ordered to match frequency of occurrence to + * minimize branching. + */ + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[9] * data[i-10]; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + else { /* order == 11 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[9] * data[i-10]; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + else { + if(order == 10) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * data[i-10]; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + else { /* order == 9 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * data[i-9]; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * data[i-8]; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + else { /* order == 7 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * data[i-7]; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + else { + if(order == 6) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * data[i-6]; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + else { /* order == 5 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * data[i-5]; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * data[i-4]; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + else { /* order == 3 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * data[i-3]; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + else { + if(order == 2) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * data[i-2]; + sum += qlp_coeff[0] * data[i-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + else { /* order == 1 */ + for(i = 0; i < (int)data_len; i++) + data[i] = residual[i] + ((qlp_coeff[0] * data[i-1]) >> lp_quantization); + } + } + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + data[i] = residual[i] + (sum >> lp_quantization); + } + } +} +#endif + +void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data) +#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) +{ + unsigned i, j; + FLAC__int64 sum; + const FLAC__int32 *r = residual, *history; + +#ifdef FLAC__OVERFLOW_DETECT_VERBOSE + fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); + for(i=0;i<order;i++) + fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); + fprintf(stderr,"\n"); +#endif + FLAC__ASSERT(order > 0); + + for(i = 0; i < data_len; i++) { + sum = 0; + history = data; + for(j = 0; j < order; j++) + sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); + if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { + fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); + break; + } + if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { + fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); + break; + } + *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); + } +} +#else /* fully unrolled version for normal use */ +{ + int i; + FLAC__int64 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + * We do unique versions up to 12th order since that's the subset limit. + * Also they are roughly ordered to match frequency of occurrence to + * minimize branching. + */ + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 11 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + } + else { + if(order == 10) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 9 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 7 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + } + else { + if(order == 6) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 5 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 3 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + } + else { + if(order == 2) { + for(i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order == 1 */ + for(i = 0; i < (int)data_len; i++) + data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); + } + } + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } +} +#endif + +#if defined(_MSC_VER) +#pragma warning ( default : 4028 ) +#endif + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, unsigned total_samples) +{ + double error_scale; + + FLAC__ASSERT(total_samples > 0); + + error_scale = 0.5 / (double)total_samples; + + return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale); +} + +double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale) +{ + if(lpc_error > 0.0) { + double bps = (double)0.5 * log(error_scale * lpc_error) / M_LN2; + if(bps >= 0.0) + return bps; + else + return 0.0; + } + else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */ + return 1e32; + } + else { + return 0.0; + } +} + +unsigned FLAC__lpc_compute_best_order(const double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order) +{ + unsigned order, indx, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */ + double bits, best_bits, error_scale; + + FLAC__ASSERT(max_order > 0); + FLAC__ASSERT(total_samples > 0); + + error_scale = 0.5 / (double)total_samples; + + best_index = 0; + best_bits = (unsigned)(-1); + + for(indx = 0, order = 1; indx < max_order; indx++, order++) { + bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[indx], error_scale) * (double)(total_samples - order) + (double)(order * overhead_bits_per_order); + if(bits < best_bits) { + best_index = indx; + best_bits = bits; + } + } + + return best_index+1; /* +1 since indx of lpc_error[] is order-1 */ +} + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/lpc_intrin_avx2.c b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_avx2.c new file mode 100644 index 0000000..f9f5ccd --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_avx2.c @@ -0,0 +1,1122 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/lpc.h" +#ifdef FLAC__AVX2_SUPPORTED + +#include "FLAC/assert.h" +#include "FLAC/format.h" + +#include <immintrin.h> /* AVX2 */ + +FLAC__SSE_TARGET("avx2") +void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + FLAC__int32 sum; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(0xffff & qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(0xffff & qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(0xffff & qlp_coeff[8 ]); + q9 = _mm256_set1_epi32(0xffff & qlp_coeff[9 ]); + q10 = _mm256_set1_epi32(0xffff & qlp_coeff[10]); + q11 = _mm256_set1_epi32(0xffff & qlp_coeff[11]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q11, _mm256_loadu_si256((const __m256i*)(data+i-12))); + mull = _mm256_madd_epi16(q10, _mm256_loadu_si256((const __m256i*)(data+i-11))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q9, _mm256_loadu_si256((const __m256i*)(data+i-10))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q8, _mm256_loadu_si256((const __m256i*)(data+i-9 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q7, _mm256_loadu_si256((const __m256i*)(data+i-8 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q6, _mm256_loadu_si256((const __m256i*)(data+i-7 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 11 */ + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(0xffff & qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(0xffff & qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(0xffff & qlp_coeff[8 ]); + q9 = _mm256_set1_epi32(0xffff & qlp_coeff[9 ]); + q10 = _mm256_set1_epi32(0xffff & qlp_coeff[10]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q10, _mm256_loadu_si256((const __m256i*)(data+i-11))); + mull = _mm256_madd_epi16(q9, _mm256_loadu_si256((const __m256i*)(data+i-10))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q8, _mm256_loadu_si256((const __m256i*)(data+i-9 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q7, _mm256_loadu_si256((const __m256i*)(data+i-8 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q6, _mm256_loadu_si256((const __m256i*)(data+i-7 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + else { + if(order == 10) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(0xffff & qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(0xffff & qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(0xffff & qlp_coeff[8 ]); + q9 = _mm256_set1_epi32(0xffff & qlp_coeff[9 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q9, _mm256_loadu_si256((const __m256i*)(data+i-10))); + mull = _mm256_madd_epi16(q8, _mm256_loadu_si256((const __m256i*)(data+i-9 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q7, _mm256_loadu_si256((const __m256i*)(data+i-8 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q6, _mm256_loadu_si256((const __m256i*)(data+i-7 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 9 */ + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(0xffff & qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(0xffff & qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(0xffff & qlp_coeff[8 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q8, _mm256_loadu_si256((const __m256i*)(data+i-9 ))); + mull = _mm256_madd_epi16(q7, _mm256_loadu_si256((const __m256i*)(data+i-8 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q6, _mm256_loadu_si256((const __m256i*)(data+i-7 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(0xffff & qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(0xffff & qlp_coeff[7 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q7, _mm256_loadu_si256((const __m256i*)(data+i-8 ))); + mull = _mm256_madd_epi16(q6, _mm256_loadu_si256((const __m256i*)(data+i-7 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 7 */ + __m256i q0, q1, q2, q3, q4, q5, q6; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(0xffff & qlp_coeff[6 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q6, _mm256_loadu_si256((const __m256i*)(data+i-7 ))); + mull = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + else { + if(order == 6) { + __m256i q0, q1, q2, q3, q4, q5; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(0xffff & qlp_coeff[5 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q5, _mm256_loadu_si256((const __m256i*)(data+i-6 ))); + mull = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 5 */ + __m256i q0, q1, q2, q3, q4; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(0xffff & qlp_coeff[4 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q4, _mm256_loadu_si256((const __m256i*)(data+i-5 ))); + mull = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + __m256i q0, q1, q2, q3; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(0xffff & qlp_coeff[3 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q3, _mm256_loadu_si256((const __m256i*)(data+i-4 ))); + mull = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 3 */ + __m256i q0, q1, q2; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(0xffff & qlp_coeff[2 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q2, _mm256_loadu_si256((const __m256i*)(data+i-3 ))); + mull = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + else { + if(order == 2) { + __m256i q0, q1; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(0xffff & qlp_coeff[1 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_madd_epi16(q1, _mm256_loadu_si256((const __m256i*)(data+i-2 ))); + mull = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 1 */ + __m256i q0; + q0 = _mm256_set1_epi32(0xffff & qlp_coeff[0 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ; + summ = _mm256_madd_epi16(q0, _mm256_loadu_si256((const __m256i*)(data+i-1 ))); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + } + for(; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 12: sum += qlp_coeff[11] * data[i-12]; + case 11: sum += qlp_coeff[10] * data[i-11]; + case 10: sum += qlp_coeff[ 9] * data[i-10]; + case 9: sum += qlp_coeff[ 8] * data[i- 9]; + case 8: sum += qlp_coeff[ 7] * data[i- 8]; + case 7: sum += qlp_coeff[ 6] * data[i- 7]; + case 6: sum += qlp_coeff[ 5] * data[i- 6]; + case 5: sum += qlp_coeff[ 4] * data[i- 5]; + case 4: sum += qlp_coeff[ 3] * data[i- 4]; + case 3: sum += qlp_coeff[ 2] * data[i- 3]; + case 2: sum += qlp_coeff[ 1] * data[i- 2]; + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + _mm256_zeroupper(); +} + +FLAC__SSE_TARGET("avx2") +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + FLAC__int32 sum; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(qlp_coeff[8 ]); + q9 = _mm256_set1_epi32(qlp_coeff[9 ]); + q10 = _mm256_set1_epi32(qlp_coeff[10]); + q11 = _mm256_set1_epi32(qlp_coeff[11]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q11, _mm256_loadu_si256((const __m256i*)(data+i-12))); + mull = _mm256_mullo_epi32(q10, _mm256_loadu_si256((const __m256i*)(data+i-11))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q9, _mm256_loadu_si256((const __m256i*)(data+i-10))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q8, _mm256_loadu_si256((const __m256i*)(data+i-9))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q7, _mm256_loadu_si256((const __m256i*)(data+i-8))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q6, _mm256_loadu_si256((const __m256i*)(data+i-7))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 11 */ + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(qlp_coeff[8 ]); + q9 = _mm256_set1_epi32(qlp_coeff[9 ]); + q10 = _mm256_set1_epi32(qlp_coeff[10]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q10, _mm256_loadu_si256((const __m256i*)(data+i-11))); + mull = _mm256_mullo_epi32(q9, _mm256_loadu_si256((const __m256i*)(data+i-10))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q8, _mm256_loadu_si256((const __m256i*)(data+i-9))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q7, _mm256_loadu_si256((const __m256i*)(data+i-8))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q6, _mm256_loadu_si256((const __m256i*)(data+i-7))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + else { + if(order == 10) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(qlp_coeff[8 ]); + q9 = _mm256_set1_epi32(qlp_coeff[9 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q9, _mm256_loadu_si256((const __m256i*)(data+i-10))); + mull = _mm256_mullo_epi32(q8, _mm256_loadu_si256((const __m256i*)(data+i-9))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q7, _mm256_loadu_si256((const __m256i*)(data+i-8))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q6, _mm256_loadu_si256((const __m256i*)(data+i-7))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 9 */ + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(qlp_coeff[7 ]); + q8 = _mm256_set1_epi32(qlp_coeff[8 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q8, _mm256_loadu_si256((const __m256i*)(data+i-9))); + mull = _mm256_mullo_epi32(q7, _mm256_loadu_si256((const __m256i*)(data+i-8))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q6, _mm256_loadu_si256((const __m256i*)(data+i-7))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(qlp_coeff[6 ]); + q7 = _mm256_set1_epi32(qlp_coeff[7 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q7, _mm256_loadu_si256((const __m256i*)(data+i-8))); + mull = _mm256_mullo_epi32(q6, _mm256_loadu_si256((const __m256i*)(data+i-7))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 7 */ + __m256i q0, q1, q2, q3, q4, q5, q6; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + q6 = _mm256_set1_epi32(qlp_coeff[6 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q6, _mm256_loadu_si256((const __m256i*)(data+i-7))); + mull = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + else { + if(order == 6) { + __m256i q0, q1, q2, q3, q4, q5; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + q5 = _mm256_set1_epi32(qlp_coeff[5 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q5, _mm256_loadu_si256((const __m256i*)(data+i-6))); + mull = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 5 */ + __m256i q0, q1, q2, q3, q4; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + q4 = _mm256_set1_epi32(qlp_coeff[4 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q4, _mm256_loadu_si256((const __m256i*)(data+i-5))); + mull = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + __m256i q0, q1, q2, q3; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + q3 = _mm256_set1_epi32(qlp_coeff[3 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q3, _mm256_loadu_si256((const __m256i*)(data+i-4))); + mull = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 3 */ + __m256i q0, q1, q2; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + q2 = _mm256_set1_epi32(qlp_coeff[2 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q2, _mm256_loadu_si256((const __m256i*)(data+i-3))); + mull = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); summ = _mm256_add_epi32(summ, mull); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + else { + if(order == 2) { + __m256i q0, q1; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + q1 = _mm256_set1_epi32(qlp_coeff[1 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ, mull; + summ = _mm256_mullo_epi32(q1, _mm256_loadu_si256((const __m256i*)(data+i-2))); + mull = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); summ = _mm256_add_epi32(summ, mull); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + else { /* order == 1 */ + __m256i q0; + q0 = _mm256_set1_epi32(qlp_coeff[0 ]); + + for(i = 0; i < (int)data_len-7; i+=8) { + __m256i summ; + summ = _mm256_mullo_epi32(q0, _mm256_loadu_si256((const __m256i*)(data+i-1))); + summ = _mm256_sra_epi32(summ, cnt); + _mm256_storeu_si256((__m256i*)(residual+i), _mm256_sub_epi32(_mm256_loadu_si256((const __m256i*)(data+i)), summ)); + } + } + } + } + for(; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 12: sum += qlp_coeff[11] * data[i-12]; + case 11: sum += qlp_coeff[10] * data[i-11]; + case 10: sum += qlp_coeff[ 9] * data[i-10]; + case 9: sum += qlp_coeff[ 8] * data[i- 9]; + case 8: sum += qlp_coeff[ 7] * data[i- 8]; + case 7: sum += qlp_coeff[ 6] * data[i- 7]; + case 6: sum += qlp_coeff[ 5] * data[i- 6]; + case 5: sum += qlp_coeff[ 4] * data[i- 5]; + case 4: sum += qlp_coeff[ 3] * data[i- 4]; + case 3: sum += qlp_coeff[ 2] * data[i- 3]; + case 2: sum += qlp_coeff[ 1] * data[i- 2]; + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + _mm256_zeroupper(); +} + +static FLAC__int32 pack_arr[8] = { 0, 2, 4, 6, 1, 3, 5, 7 }; + +FLAC__SSE_TARGET("avx2") +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + FLAC__int64 sum; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + __m256i pack = _mm256_loadu_si256((const __m256i *)pack_arr); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + FLAC__ASSERT(lp_quantization <= 32); /* there's no _mm256_sra_epi64() so we have to use _mm256_srl_epi64() */ + + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + q6 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[6 ])); + q7 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[7 ])); + q8 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[8 ])); + q9 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[9 ])); + q10 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[10])); + q11 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[11])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q11, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-12)))); + mull = _mm256_mul_epi32(q10, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-11)))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q9, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-10)))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q8, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-9 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q7, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-8 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q6, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-7 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + else { /* order == 11 */ + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + q6 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[6 ])); + q7 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[7 ])); + q8 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[8 ])); + q9 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[9 ])); + q10 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[10])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q10, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-11)))); + mull = _mm256_mul_epi32(q9, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-10)))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q8, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-9 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q7, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-8 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q6, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-7 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + } + else { + if(order == 10) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + q6 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[6 ])); + q7 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[7 ])); + q8 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[8 ])); + q9 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[9 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q9, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-10)))); + mull = _mm256_mul_epi32(q8, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-9 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q7, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-8 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q6, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-7 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + else { /* order == 9 */ + __m256i q0, q1, q2, q3, q4, q5, q6, q7, q8; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + q6 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[6 ])); + q7 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[7 ])); + q8 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[8 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q8, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-9 )))); + mull = _mm256_mul_epi32(q7, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-8 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q6, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-7 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + __m256i q0, q1, q2, q3, q4, q5, q6, q7; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + q6 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[6 ])); + q7 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[7 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q7, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-8 )))); + mull = _mm256_mul_epi32(q6, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-7 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + else { /* order == 7 */ + __m256i q0, q1, q2, q3, q4, q5, q6; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + q6 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[6 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q6, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-7 )))); + mull = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + } + else { + if(order == 6) { + __m256i q0, q1, q2, q3, q4, q5; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + q5 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[5 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q5, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-6 )))); + mull = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + else { /* order == 5 */ + __m256i q0, q1, q2, q3, q4; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + q4 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[4 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q4, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-5 )))); + mull = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + __m256i q0, q1, q2, q3; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + q3 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[3 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q3, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-4 )))); + mull = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + else { /* order == 3 */ + __m256i q0, q1, q2; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + q2 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[2 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q2, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-3 )))); + mull = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); summ = _mm256_add_epi64(summ, mull); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + } + else { + if(order == 2) { + __m256i q0, q1; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + q1 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[1 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ, mull; + summ = _mm256_mul_epi32(q1, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-2 )))); + mull = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); summ = _mm256_add_epi64(summ, mull); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + else { /* order == 1 */ + __m256i q0; + q0 = _mm256_cvtepu32_epi64(_mm_set1_epi32(qlp_coeff[0 ])); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m256i summ; + summ = _mm256_mul_epi32(q0, _mm256_cvtepu32_epi64(_mm_loadu_si128((const __m128i*)(data+i-1 )))); + summ = _mm256_permutevar8x32_epi32(_mm256_srl_epi64(summ, cnt), pack); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), _mm256_castsi256_si128(summ))); + } + } + } + } + for(; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 12: sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + case 11: sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + case 10: sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; + case 9: sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; + case 8: sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; + case 7: sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; + case 6: sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; + case 5: sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; + case 4: sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; + case 3: sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; + case 2: sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; + case 1: sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + _mm256_zeroupper(); +} + +#endif /* FLAC__AVX2_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse.c b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse.c new file mode 100644 index 0000000..430e73f --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse.c @@ -0,0 +1,454 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/lpc.h" +#ifdef FLAC__SSE_SUPPORTED +#include "FLAC/assert.h" +#include "FLAC/format.h" + +#include <xmmintrin.h> /* SSE */ + +/* new routines: more unaligned loads, less shuffle + * old routines: less unaligned loads, more shuffle + * these *_old routines are equivalent to the ASM routines in ia32/lpc_asm.nasm + */ + +/* new routines: faster on current Intel (starting from Core i aka Nehalem) and all AMD CPUs */ + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + int i; + int limit = data_len - 4; + __m128 sum0; + + (void) lag; + FLAC__ASSERT(lag <= 4); + FLAC__ASSERT(lag <= data_len); + + sum0 = _mm_setzero_ps(); + + for(i = 0; i <= limit; i++) { + __m128 d, d0; + d0 = _mm_loadu_ps(data+i); + d = d0; d = _mm_shuffle_ps(d, d, 0); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); + } + + { + __m128 d0 = _mm_setzero_ps(); + limit++; if(limit < 0) limit = 0; + + for(i = data_len-1; i >= limit; i--) { + __m128 d; + d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); + d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); + d0 = _mm_move_ss(d0, d); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); + } + } + + _mm_storeu_ps(autoc, sum0); +} + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + int i; + int limit = data_len - 8; + __m128 sum0, sum1; + + (void) lag; + FLAC__ASSERT(lag <= 8); + FLAC__ASSERT(lag <= data_len); + + sum0 = _mm_setzero_ps(); + sum1 = _mm_setzero_ps(); + + for(i = 0; i <= limit; i++) { + __m128 d, d0, d1; + d0 = _mm_loadu_ps(data+i); + d1 = _mm_loadu_ps(data+i+4); + d = d0; d = _mm_shuffle_ps(d, d, 0); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d)); + } + + { + __m128 d0 = _mm_setzero_ps(); + __m128 d1 = _mm_setzero_ps(); + limit++; if(limit < 0) limit = 0; + + for(i = data_len-1; i >= limit; i--) { + __m128 d; + d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); + d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3)); + d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); + d1 = _mm_move_ss(d1, d0); + d0 = _mm_move_ss(d0, d); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1)); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); + } + } + + _mm_storeu_ps(autoc, sum0); + _mm_storeu_ps(autoc+4, sum1); +} + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + int i; + int limit = data_len - 12; + __m128 sum0, sum1, sum2; + + (void) lag; + FLAC__ASSERT(lag <= 12); + FLAC__ASSERT(lag <= data_len); + + sum0 = _mm_setzero_ps(); + sum1 = _mm_setzero_ps(); + sum2 = _mm_setzero_ps(); + + for(i = 0; i <= limit; i++) { + __m128 d, d0, d1, d2; + d0 = _mm_loadu_ps(data+i); + d1 = _mm_loadu_ps(data+i+4); + d2 = _mm_loadu_ps(data+i+8); + d = d0; d = _mm_shuffle_ps(d, d, 0); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d)); + sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d)); + } + + { + __m128 d0 = _mm_setzero_ps(); + __m128 d1 = _mm_setzero_ps(); + __m128 d2 = _mm_setzero_ps(); + limit++; if(limit < 0) limit = 0; + + for(i = data_len-1; i >= limit; i--) { + __m128 d; + d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); + d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3)); + d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3)); + d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); + d2 = _mm_move_ss(d2, d1); + d1 = _mm_move_ss(d1, d0); + d0 = _mm_move_ss(d0, d); + sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2)); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1)); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); + } + } + + _mm_storeu_ps(autoc, sum0); + _mm_storeu_ps(autoc+4, sum1); + _mm_storeu_ps(autoc+8, sum2); +} + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + int i; + int limit = data_len - 16; + __m128 sum0, sum1, sum2, sum3; + + (void) lag; + FLAC__ASSERT(lag <= 16); + FLAC__ASSERT(lag <= data_len); + + sum0 = _mm_setzero_ps(); + sum1 = _mm_setzero_ps(); + sum2 = _mm_setzero_ps(); + sum3 = _mm_setzero_ps(); + + for(i = 0; i <= limit; i++) { + __m128 d, d0, d1, d2, d3; + d0 = _mm_loadu_ps(data+i); + d1 = _mm_loadu_ps(data+i+4); + d2 = _mm_loadu_ps(data+i+8); + d3 = _mm_loadu_ps(data+i+12); + d = d0; d = _mm_shuffle_ps(d, d, 0); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d)); + sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d)); + sum3 = _mm_add_ps(sum3, _mm_mul_ps(d3, d)); + } + + { + __m128 d0 = _mm_setzero_ps(); + __m128 d1 = _mm_setzero_ps(); + __m128 d2 = _mm_setzero_ps(); + __m128 d3 = _mm_setzero_ps(); + limit++; if(limit < 0) limit = 0; + + for(i = data_len-1; i >= limit; i--) { + __m128 d; + d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); + d3 = _mm_shuffle_ps(d3, d3, _MM_SHUFFLE(2,1,0,3)); + d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3)); + d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3)); + d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); + d3 = _mm_move_ss(d3, d2); + d2 = _mm_move_ss(d2, d1); + d1 = _mm_move_ss(d1, d0); + d0 = _mm_move_ss(d0, d); + sum3 = _mm_add_ps(sum3, _mm_mul_ps(d, d3)); + sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2)); + sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1)); + sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); + } + } + + _mm_storeu_ps(autoc, sum0); + _mm_storeu_ps(autoc+4, sum1); + _mm_storeu_ps(autoc+8, sum2); + _mm_storeu_ps(autoc+12,sum3); +} + +/* old routines: faster on older Intel CPUs (up to Core 2) */ + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + __m128 xmm0, xmm2, xmm5; + + (void) lag; + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= 4); + FLAC__ASSERT(lag <= data_len); + FLAC__ASSERT(data_len > 0); + + xmm5 = _mm_setzero_ps(); + + xmm0 = _mm_load_ss(data++); + xmm2 = xmm0; + xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); + + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm5 = _mm_add_ps(xmm5, xmm0); + + data_len--; + + while(data_len) + { + xmm0 = _mm_load1_ps(data++); + + xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); + xmm2 = _mm_move_ss(xmm2, xmm0); + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm5 = _mm_add_ps(xmm5, xmm0); + + data_len--; + } + + _mm_storeu_ps(autoc, xmm5); +} + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + __m128 xmm0, xmm1, xmm2, xmm3, xmm5, xmm6; + + (void) lag; + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= 8); + FLAC__ASSERT(lag <= data_len); + FLAC__ASSERT(data_len > 0); + + xmm5 = _mm_setzero_ps(); + xmm6 = _mm_setzero_ps(); + + xmm0 = _mm_load_ss(data++); + xmm2 = xmm0; + xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); + xmm3 = _mm_setzero_ps(); + + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm5 = _mm_add_ps(xmm5, xmm0); + + data_len--; + + while(data_len) + { + xmm0 = _mm_load1_ps(data++); + + xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); + xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3)); + xmm3 = _mm_move_ss(xmm3, xmm2); + xmm2 = _mm_move_ss(xmm2, xmm0); + + xmm1 = xmm0; + xmm1 = _mm_mul_ps(xmm1, xmm3); + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm6 = _mm_add_ps(xmm6, xmm1); + xmm5 = _mm_add_ps(xmm5, xmm0); + + data_len--; + } + + _mm_storeu_ps(autoc, xmm5); + _mm_storeu_ps(autoc+4, xmm6); +} + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + + (void) lag; + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= 12); + FLAC__ASSERT(lag <= data_len); + FLAC__ASSERT(data_len > 0); + + xmm5 = _mm_setzero_ps(); + xmm6 = _mm_setzero_ps(); + xmm7 = _mm_setzero_ps(); + + xmm0 = _mm_load_ss(data++); + xmm2 = xmm0; + xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); + xmm3 = _mm_setzero_ps(); + xmm4 = _mm_setzero_ps(); + + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm5 = _mm_add_ps(xmm5, xmm0); + + data_len--; + + while(data_len) + { + xmm0 = _mm_load1_ps(data++); + + xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); + xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3)); + xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3)); + xmm4 = _mm_move_ss(xmm4, xmm3); + xmm3 = _mm_move_ss(xmm3, xmm2); + xmm2 = _mm_move_ss(xmm2, xmm0); + + xmm1 = xmm0; + xmm1 = _mm_mul_ps(xmm1, xmm2); + xmm5 = _mm_add_ps(xmm5, xmm1); + xmm1 = xmm0; + xmm1 = _mm_mul_ps(xmm1, xmm3); + xmm6 = _mm_add_ps(xmm6, xmm1); + xmm0 = _mm_mul_ps(xmm0, xmm4); + xmm7 = _mm_add_ps(xmm7, xmm0); + + data_len--; + } + + _mm_storeu_ps(autoc, xmm5); + _mm_storeu_ps(autoc+4, xmm6); + _mm_storeu_ps(autoc+8, xmm7); +} + +FLAC__SSE_TARGET("sse") +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) +{ + __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9; + + (void) lag; + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= 16); + FLAC__ASSERT(lag <= data_len); + FLAC__ASSERT(data_len > 0); + + xmm6 = _mm_setzero_ps(); + xmm7 = _mm_setzero_ps(); + xmm8 = _mm_setzero_ps(); + xmm9 = _mm_setzero_ps(); + + xmm0 = _mm_load_ss(data++); + xmm2 = xmm0; + xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); + xmm3 = _mm_setzero_ps(); + xmm4 = _mm_setzero_ps(); + xmm5 = _mm_setzero_ps(); + + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm6 = _mm_add_ps(xmm6, xmm0); + + data_len--; + + while(data_len) + { + xmm0 = _mm_load1_ps(data++); + + /* shift xmm5:xmm4:xmm3:xmm2 left by one float */ + xmm5 = _mm_shuffle_ps(xmm5, xmm5, _MM_SHUFFLE(2,1,0,3)); + xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3)); + xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3)); + xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); + xmm5 = _mm_move_ss(xmm5, xmm4); + xmm4 = _mm_move_ss(xmm4, xmm3); + xmm3 = _mm_move_ss(xmm3, xmm2); + xmm2 = _mm_move_ss(xmm2, xmm0); + + /* xmm9|xmm8|xmm7|xmm6 += xmm0|xmm0|xmm0|xmm0 * xmm5|xmm4|xmm3|xmm2 */ + xmm1 = xmm0; + xmm1 = _mm_mul_ps(xmm1, xmm5); + xmm9 = _mm_add_ps(xmm9, xmm1); + xmm1 = xmm0; + xmm1 = _mm_mul_ps(xmm1, xmm4); + xmm8 = _mm_add_ps(xmm8, xmm1); + xmm1 = xmm0; + xmm1 = _mm_mul_ps(xmm1, xmm3); + xmm7 = _mm_add_ps(xmm7, xmm1); + xmm0 = _mm_mul_ps(xmm0, xmm2); + xmm6 = _mm_add_ps(xmm6, xmm0); + + data_len--; + } + + _mm_storeu_ps(autoc, xmm6); + _mm_storeu_ps(autoc+4, xmm7); + _mm_storeu_ps(autoc+8, xmm8); + _mm_storeu_ps(autoc+12,xmm9); +} + +#endif /* FLAC__SSE_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse2.c b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse2.c new file mode 100644 index 0000000..1383394 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse2.c @@ -0,0 +1,1090 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/lpc.h" +#ifdef FLAC__SSE2_SUPPORTED + +#include "FLAC/assert.h" +#include "FLAC/format.h" + +#include <emmintrin.h> /* SSE2 */ + +#define RESIDUAL16_RESULT(xmmN) curr = *data++; *residual++ = curr - (_mm_cvtsi128_si32(xmmN) >> lp_quantization); +#define DATA16_RESULT(xmmN) curr = *residual++ + (_mm_cvtsi128_si32(xmmN) >> lp_quantization); *data++ = curr; + +#define RESIDUAL32_RESULT(xmmN) residual[i] = data[i] - (_mm_cvtsi128_si32(xmmN) >> lp_quantization); +#define DATA32_RESULT(xmmN) data[i] = residual[i] + (_mm_cvtsi128_si32(xmmN) >> lp_quantization); + +FLAC__SSE_TARGET("sse2") +void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + FLAC__int32 sum; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + q9 = _mm_cvtsi32_si128(0xffff & qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); + q10 = _mm_cvtsi32_si128(0xffff & qlp_coeff[10]); q10 = _mm_shuffle_epi32(q10, _MM_SHUFFLE(0,0,0,0)); + q11 = _mm_cvtsi32_si128(0xffff & qlp_coeff[11]); q11 = _mm_shuffle_epi32(q11, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q11, _mm_loadu_si128((const __m128i*)(data+i-12))); + mull = _mm_madd_epi16(q10, _mm_loadu_si128((const __m128i*)(data+i-11))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 11 */ + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + q9 = _mm_cvtsi32_si128(0xffff & qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); + q10 = _mm_cvtsi32_si128(0xffff & qlp_coeff[10]); q10 = _mm_shuffle_epi32(q10, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q10, _mm_loadu_si128((const __m128i*)(data+i-11))); + mull = _mm_madd_epi16(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + else { + if(order == 10) { + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + q9 = _mm_cvtsi32_si128(0xffff & qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); + mull = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 9 */ + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); + mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + __m128i q0, q1, q2, q3, q4, q5, q6, q7; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); + mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 7 */ + __m128i q0, q1, q2, q3, q4, q5, q6; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); + mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + else { + if(order == 6) { + __m128i q0, q1, q2, q3, q4, q5; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); + mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 5 */ + __m128i q0, q1, q2, q3, q4; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); + mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + __m128i q0, q1, q2, q3; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); + mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 3 */ + __m128i q0, q1, q2; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); + mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + else { + if(order == 2) { + __m128i q0, q1; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); + mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 1 */ + __m128i q0; + q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ; + summ = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + } + for(; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 12: sum += qlp_coeff[11] * data[i-12]; + case 11: sum += qlp_coeff[10] * data[i-11]; + case 10: sum += qlp_coeff[ 9] * data[i-10]; + case 9: sum += qlp_coeff[ 8] * data[i- 9]; + case 8: sum += qlp_coeff[ 7] * data[i- 8]; + case 7: sum += qlp_coeff[ 6] * data[i- 7]; + case 6: sum += qlp_coeff[ 5] * data[i- 6]; + case 5: sum += qlp_coeff[ 4] * data[i- 5]; + case 4: sum += qlp_coeff[ 3] * data[i- 4]; + case 3: sum += qlp_coeff[ 2] * data[i- 3]; + case 2: sum += qlp_coeff[ 1] * data[i- 2]; + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } +} + +FLAC__SSE_TARGET("sse2") +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + if(order <= 12) { + if(order > 8) { /* order == 9, 10, 11, 12 */ + if(order > 10) { /* order == 11, 12 */ + if(order == 12) { + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); // 0 0 q[1] q[0] + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); // 0 0 q[3] q[2] + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); // 0 0 q[5] q[4] + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); // 0 0 q[7] q[6] + xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); // 0 0 q[9] q[8] + xmm5 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+10)); // 0 0 q[11] q[10] + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); // 0 q[1] 0 q[0] + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); // 0 q[3] 0 q[2] + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); // 0 q[5] 0 q[4] + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); // 0 q[7] 0 q[6] + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); // 0 q[9] 0 q[8] + xmm5 = _mm_shuffle_epi32(xmm5, _MM_SHUFFLE(3,1,2,0)); // 0 q[11] 0 q[10] + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[11] * data[i-12]; + //sum += qlp_coeff[10] * data[i-11]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-12)); // 0 0 d[i-11] d[i-12] + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); // 0 d[i-12] 0 d[i-11] + xmm7 = _mm_mul_epu32(xmm7, xmm5); /* we use _unsigned_ multiplication and discard high dword of the result values */ + + //sum += qlp_coeff[9] * data[i-10]; + //sum += qlp_coeff[8] * data[i-9]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-10)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm4); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[7] * data[i-8]; + //sum += qlp_coeff[6] * data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm3); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm2); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + else { /* order == 11 */ + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); + xmm5 = _mm_cvtsi32_si128(qlp_coeff[10]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[10] * data[i-11]; + xmm7 = _mm_cvtsi32_si128(data[i-11]); + xmm7 = _mm_mul_epu32(xmm7, xmm5); + + //sum += qlp_coeff[9] * data[i-10]; + //sum += qlp_coeff[8] * data[i-9]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-10)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm4); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[7] * data[i-8]; + //sum += qlp_coeff[6] * data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm3); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm2); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + } + else { /* order == 9, 10 */ + if(order == 10) { + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[9] * data[i-10]; + //sum += qlp_coeff[8] * data[i-9]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-10)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epu32(xmm7, xmm4); + + //sum += qlp_coeff[7] * data[i-8]; + //sum += qlp_coeff[6] * data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm3); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm2); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + else { /* order == 9 */ + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + xmm4 = _mm_cvtsi32_si128(qlp_coeff[8]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[8] * data[i-9]; + xmm7 = _mm_cvtsi32_si128(data[i-9]); + xmm7 = _mm_mul_epu32(xmm7, xmm4); + + //sum += qlp_coeff[7] * data[i-8]; + //sum += qlp_coeff[6] * data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm3); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm2); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + } + } + else if(order > 4) { /* order == 5, 6, 7, 8 */ + if(order > 6) { /* order == 7, 8 */ + if(order == 8) { + __m128i xmm0, xmm1, xmm2, xmm3, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[7] * data[i-8]; + //sum += qlp_coeff[6] * data[i-7]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epu32(xmm7, xmm3); + + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm2); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + else { /* order == 7 */ + __m128i xmm0, xmm1, xmm2, xmm3, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_cvtsi32_si128(qlp_coeff[6]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[6] * data[i-7]; + xmm7 = _mm_cvtsi32_si128(data[i-7]); + xmm7 = _mm_mul_epu32(xmm7, xmm3); + + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm2); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + } + else { /* order == 5, 6 */ + if(order == 6) { + __m128i xmm0, xmm1, xmm2, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[5] * data[i-6]; + //sum += qlp_coeff[4] * data[i-5]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epu32(xmm7, xmm2); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + else { /* order == 5 */ + __m128i xmm0, xmm1, xmm2, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_cvtsi32_si128(qlp_coeff[4]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[4] * data[i-5]; + xmm7 = _mm_cvtsi32_si128(data[i-5]); + xmm7 = _mm_mul_epu32(xmm7, xmm2); + + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm1); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + } + } + else { /* order == 1, 2, 3, 4 */ + if(order > 2) { /* order == 3, 4 */ + if(order == 4) { + __m128i xmm0, xmm1, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[3] * data[i-4]; + //sum += qlp_coeff[2] * data[i-3]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epu32(xmm7, xmm1); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + else { /* order == 3 */ + __m128i xmm0, xmm1, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_cvtsi32_si128(qlp_coeff[2]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[2] * data[i-3]; + xmm7 = _mm_cvtsi32_si128(data[i-3]); + xmm7 = _mm_mul_epu32(xmm7, xmm1); + + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epu32(xmm6, xmm0); + xmm7 = _mm_add_epi32(xmm7, xmm6); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + } + else { /* order == 1, 2 */ + if(order == 2) { + __m128i xmm0, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[1] * data[i-2]; + //sum += qlp_coeff[0] * data[i-1]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epu32(xmm7, xmm0); + + xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL32_RESULT(xmm7); + } + } + else { /* order == 1 */ + for(i = 0; i < (int)data_len; i++) + residual[i] = data[i] - ((qlp_coeff[0] * data[i-1]) >> lp_quantization); + } + } + } + } + else { /* order > 12 */ + FLAC__int32 sum; + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } +} + +#if defined FLAC__CPU_IA32 && !defined FLAC__HAS_NASM /* unused for x64; not better than MMX asm */ + +FLAC__SSE_TARGET("sse2") +void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) +{ + if (order < 8 || order > 12) { + FLAC__lpc_restore_signal(residual, data_len, qlp_coeff, order, lp_quantization, data); + return; + } + if (data_len == 0) + return; + + FLAC__ASSERT(order >= 8); + FLAC__ASSERT(order <= 12); + + if(order > 8) { /* order == 9, 10, 11, 12 */ + FLAC__int32 curr; + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + xmm0 = _mm_loadu_si128((const __m128i*)(qlp_coeff+0)); + xmm6 = _mm_loadu_si128((const __m128i*)(qlp_coeff+4)); + xmm1 = _mm_loadu_si128((const __m128i*)(qlp_coeff+8)); /* read 0 to 3 uninitialized coeffs... */ + switch(order) /* ...and zero them out */ + { + case 9: + xmm1 = _mm_slli_si128(xmm1, 12); xmm1 = _mm_srli_si128(xmm1, 12); break; + case 10: + xmm1 = _mm_slli_si128(xmm1, 8); xmm1 = _mm_srli_si128(xmm1, 8); break; + case 11: + xmm1 = _mm_slli_si128(xmm1, 4); xmm1 = _mm_srli_si128(xmm1, 4); break; + } + xmm2 = _mm_setzero_si128(); + xmm0 = _mm_packs_epi32(xmm0, xmm6); + xmm1 = _mm_packs_epi32(xmm1, xmm2); + + xmm4 = _mm_loadu_si128((const __m128i*)(data-12)); + xmm5 = _mm_loadu_si128((const __m128i*)(data-8)); + xmm3 = _mm_loadu_si128((const __m128i*)(data-4)); + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(0,1,2,3)); + xmm5 = _mm_shuffle_epi32(xmm5, _MM_SHUFFLE(0,1,2,3)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(0,1,2,3)); + xmm4 = _mm_packs_epi32(xmm4, xmm2); + xmm3 = _mm_packs_epi32(xmm3, xmm5); + + xmm7 = _mm_slli_si128(xmm1, 2); + xmm7 = _mm_or_si128(xmm7, _mm_srli_si128(xmm0, 14)); + xmm2 = _mm_slli_si128(xmm0, 2); + + /* xmm0, xmm1: qlp_coeff + xmm2, xmm7: qlp_coeff << 16 bit + xmm3, xmm4: data */ + + xmm5 = _mm_madd_epi16(xmm4, xmm1); + xmm6 = _mm_madd_epi16(xmm3, xmm0); + xmm6 = _mm_add_epi32(xmm6, xmm5); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 8)); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 4)); + + DATA16_RESULT(xmm6); + + data_len--; + + if(data_len % 2) { + xmm6 = _mm_srli_si128(xmm3, 14); + xmm4 = _mm_slli_si128(xmm4, 2); + xmm3 = _mm_slli_si128(xmm3, 2); + xmm4 = _mm_or_si128(xmm4, xmm6); + xmm3 = _mm_insert_epi16(xmm3, curr, 0); + + xmm5 = _mm_madd_epi16(xmm4, xmm1); + xmm6 = _mm_madd_epi16(xmm3, xmm0); + xmm6 = _mm_add_epi32(xmm6, xmm5); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 8)); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 4)); + + DATA16_RESULT(xmm6); + + data_len--; + } + + while(data_len) { /* data_len is a multiple of 2 */ + /* 1 _mm_slli_si128 per data element less but we need shifted qlp_coeff in xmm2:xmm7 */ + xmm6 = _mm_srli_si128(xmm3, 12); + xmm4 = _mm_slli_si128(xmm4, 4); + xmm3 = _mm_slli_si128(xmm3, 4); + xmm4 = _mm_or_si128(xmm4, xmm6); + xmm3 = _mm_insert_epi16(xmm3, curr, 1); + + xmm5 = _mm_madd_epi16(xmm4, xmm7); + xmm6 = _mm_madd_epi16(xmm3, xmm2); + xmm6 = _mm_add_epi32(xmm6, xmm5); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 8)); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 4)); + + DATA16_RESULT(xmm6); + + xmm3 = _mm_insert_epi16(xmm3, curr, 0); + + xmm5 = _mm_madd_epi16(xmm4, xmm1); + xmm6 = _mm_madd_epi16(xmm3, xmm0); + xmm6 = _mm_add_epi32(xmm6, xmm5); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 8)); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 4)); + + DATA16_RESULT(xmm6); + + data_len-=2; + } + } /* endif(order > 8) */ + else + { + FLAC__int32 curr; + __m128i xmm0, xmm1, xmm3, xmm6; + xmm0 = _mm_loadu_si128((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadu_si128((const __m128i*)(qlp_coeff+4)); + xmm0 = _mm_packs_epi32(xmm0, xmm1); + + xmm1 = _mm_loadu_si128((const __m128i*)(data-8)); + xmm3 = _mm_loadu_si128((const __m128i*)(data-4)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(0,1,2,3)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(0,1,2,3)); + xmm3 = _mm_packs_epi32(xmm3, xmm1); + + /* xmm0: qlp_coeff + xmm3: data */ + + xmm6 = _mm_madd_epi16(xmm3, xmm0); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 8)); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 4)); + + DATA16_RESULT(xmm6); + + data_len--; + + while(data_len) { + xmm3 = _mm_slli_si128(xmm3, 2); + xmm3 = _mm_insert_epi16(xmm3, curr, 0); + + xmm6 = _mm_madd_epi16(xmm3, xmm0); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 8)); + xmm6 = _mm_add_epi32(xmm6, _mm_srli_si128(xmm6, 4)); + + DATA16_RESULT(xmm6); + + data_len--; + } + } +} + +#endif /* defined FLAC__CPU_IA32 && !defined FLAC__HAS_NASM */ + +#endif /* FLAC__SSE2_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse41.c b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse41.c new file mode 100644 index 0000000..bef73f4 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/lpc_intrin_sse41.c @@ -0,0 +1,1314 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/lpc.h" +#ifdef FLAC__SSE4_1_SUPPORTED + +#include "FLAC/assert.h" +#include "FLAC/format.h" + +#include <smmintrin.h> /* SSE4.1 */ + +#if defined FLAC__CPU_IA32 /* unused for x64 */ + +#define RESIDUAL64_RESULT(xmmN) residual[i] = data[i] - _mm_cvtsi128_si32(_mm_srl_epi64(xmmN, cnt)) +#define RESIDUAL64_RESULT1(xmmN) residual[i] = data[i] - _mm_cvtsi128_si32(_mm_srli_epi64(xmmN, lp_quantization)) + +FLAC__SSE_TARGET("sse4.1") +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + FLAC__ASSERT(lp_quantization <= 32); /* there's no _mm_sra_epi64() so we have to use _mm_srl_epi64() */ + + if(order <= 12) { + if(order > 8) { /* order == 9, 10, 11, 12 */ + if(order > 10) { /* order == 11, 12 */ + if(order == 12) { + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); // 0 0 q[1] q[0] + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); // 0 0 q[3] q[2] + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); // 0 0 q[5] q[4] + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); // 0 0 q[7] q[6] + xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); // 0 0 q[9] q[8] + xmm5 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+10)); // 0 0 q[11] q[10] + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); // 0 q[1] 0 q[0] + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); // 0 q[3] 0 q[2] + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); // 0 q[5] 0 q[4] + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); // 0 q[7] 0 q[6] + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); // 0 q[9] 0 q[8] + xmm5 = _mm_shuffle_epi32(xmm5, _MM_SHUFFLE(3,1,2,0)); // 0 q[11] 0 q[10] + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + //sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-12)); // 0 0 d[i-11] d[i-12] + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); // 0 d[i-12] 0 d[i-11] + xmm7 = _mm_mul_epi32(xmm7, xmm5); + + //sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + //sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-10)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm4); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + //sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm3); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm2); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT1(xmm7); + } + } + else { /* order == 11 */ + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); + xmm5 = _mm_cvtsi32_si128(qlp_coeff[10]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[10] * (FLAC__int64)data[i-11]; + xmm7 = _mm_cvtsi32_si128(data[i-11]); + xmm7 = _mm_mul_epi32(xmm7, xmm5); + + //sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + //sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-10)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm4); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + //sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm3); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm2); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT1(xmm7); + } + } + } + else { /* order == 9, 10 */ + if(order == 10) { + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; + //sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-10)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epi32(xmm7, xmm4); + + //sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + //sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm3); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm2); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + else { /* order == 9 */ + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + xmm4 = _mm_cvtsi32_si128(qlp_coeff[8]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[8] * (FLAC__int64)data[i-9]; + xmm7 = _mm_cvtsi32_si128(data[i-9]); + xmm7 = _mm_mul_epi32(xmm7, xmm4); + + //sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + //sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm3); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm2); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + } + } + else if(order > 4) { /* order == 5, 6, 7, 8 */ + if(order > 6) { /* order == 7, 8 */ + if(order == 8) { + __m128i xmm0, xmm1, xmm2, xmm3, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; + //sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-8)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epi32(xmm7, xmm3); + + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm2); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + else { /* order == 7 */ + __m128i xmm0, xmm1, xmm2, xmm3, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + xmm3 = _mm_cvtsi32_si128(qlp_coeff[6]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[6] * (FLAC__int64)data[i-7]; + xmm7 = _mm_cvtsi32_si128(data[i-7]); + xmm7 = _mm_mul_epi32(xmm7, xmm3); + + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm2); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + } + else { /* order == 5, 6 */ + if(order == 6) { + __m128i xmm0, xmm1, xmm2, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; + //sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-6)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epi32(xmm7, xmm2); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + else { /* order == 5 */ + __m128i xmm0, xmm1, xmm2, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + xmm2 = _mm_cvtsi32_si128(qlp_coeff[4]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[4] * (FLAC__int64)data[i-5]; + xmm7 = _mm_cvtsi32_si128(data[i-5]); + xmm7 = _mm_mul_epi32(xmm7, xmm2); + + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm1); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + } + } + else { /* order == 1, 2, 3, 4 */ + if(order > 2) { /* order == 3, 4 */ + if(order == 4) { + __m128i xmm0, xmm1, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; + //sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-4)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epi32(xmm7, xmm1); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + else { /* order == 3 */ + __m128i xmm0, xmm1, xmm6, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm1 = _mm_cvtsi32_si128(qlp_coeff[2]); + + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum = qlp_coeff[2] * (FLAC__int64)data[i-3]; + xmm7 = _mm_cvtsi32_si128(data[i-3]); + xmm7 = _mm_mul_epi32(xmm7, xmm1); + + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); + xmm6 = _mm_mul_epi32(xmm6, xmm0); + xmm7 = _mm_add_epi64(xmm7, xmm6); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + } + else { /* order == 1, 2 */ + if(order == 2) { + __m128i xmm0, xmm7; + xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); + + for(i = 0; i < (int)data_len; i++) { + //sum = 0; + //sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; + //sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-2)); + xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); + xmm7 = _mm_mul_epi32(xmm7, xmm0); + + xmm7 = _mm_add_epi64(xmm7, _mm_srli_si128(xmm7, 8)); + RESIDUAL64_RESULT(xmm7); + } + } + else { /* order == 1 */ + __m128i xmm0, xmm7; + xmm0 = _mm_cvtsi32_si128(qlp_coeff[0]); + + for(i = 0; i < (int)data_len; i++) { + //sum = qlp_coeff[0] * (FLAC__int64)data[i-1]; + xmm7 = _mm_cvtsi32_si128(data[i-1]); + xmm7 = _mm_mul_epi32(xmm7, xmm0); + RESIDUAL64_RESULT(xmm7); + } + } + } + } + } + else { /* order > 12 */ + FLAC__int64 sum; + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } +} + +FLAC__SSE_TARGET("sse4.1") +void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) +{ + int i; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + + if (!data_len) + return; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + FLAC__ASSERT(lp_quantization <= 32); /* there's no _mm_sra_epi64() so we have to use _mm_srl_epi64() */ + + if(order <= 12) { + if(order > 8) { /* order == 9, 10, 11, 12 */ + if(order > 10) { /* order == 11, 12 */ + __m128i qlp[6], dat[6]; + __m128i summ, temp; + qlp[0] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); // 0 0 q[1] q[0] + qlp[1] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); // 0 0 q[3] q[2] + qlp[2] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); // 0 0 q[5] q[4] + qlp[3] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); // 0 0 q[7] q[6] + qlp[4] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); // 0 0 q[9] q[8] + if (order == 12) + qlp[5] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+10)); // 0 0 q[11] q[10] + else + qlp[5] = _mm_cvtsi32_si128(qlp_coeff[10]); // 0 0 0 q[10] + + qlp[0] = _mm_shuffle_epi32(qlp[0], _MM_SHUFFLE(2,0,3,1)); // 0 q[0] 0 q[1] + qlp[1] = _mm_shuffle_epi32(qlp[1], _MM_SHUFFLE(2,0,3,1)); // 0 q[2] 0 q[3] + qlp[2] = _mm_shuffle_epi32(qlp[2], _MM_SHUFFLE(2,0,3,1)); // 0 q[4] 0 q[5] + qlp[3] = _mm_shuffle_epi32(qlp[3], _MM_SHUFFLE(2,0,3,1)); // 0 q[5] 0 q[7] + qlp[4] = _mm_shuffle_epi32(qlp[4], _MM_SHUFFLE(2,0,3,1)); // 0 q[8] 0 q[9] + qlp[5] = _mm_shuffle_epi32(qlp[5], _MM_SHUFFLE(2,0,3,1)); // 0 q[10] 0 q[11] + + dat[5] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-12))); // ? d[i-11] ? d[i-12] + dat[4] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-10))); // ? d[i-9] ? d[i-10] + dat[3] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-8 ))); // ? d[i-7] ? d[i-8] + dat[2] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-6 ))); // ? d[i-5] ? d[i-6] + dat[1] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-4 ))); // ? d[i-3] ? d[i-4] + dat[0] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-2 ))); // ? d[i-1] ? d[i-2] + + summ = _mm_mul_epi32(dat[5], qlp[5]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[4], qlp[4])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[3], qlp[3])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[2], qlp[2])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); // ?_64 sum_64 + summ = _mm_srl_epi64(summ, cnt); // ?_64 (sum >> lp_quantization)_64 == ?_32 ?_32 ?_32 (sum >> lp_quantization)_32 + temp = _mm_cvtsi32_si128(residual[0]); // 0 0 0 r[i] + temp = _mm_add_epi32(temp, summ); // ? ? ? d[i] + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + dat[5] = _mm_alignr_epi8(dat[4], dat[5], 8); // ? d[i-10] ? d[i-11] + dat[4] = _mm_alignr_epi8(dat[3], dat[4], 8); // ? d[i-8] ? d[i-9] + dat[3] = _mm_alignr_epi8(dat[2], dat[3], 8); // ? d[i-6] ? d[i-7] + dat[2] = _mm_alignr_epi8(dat[1], dat[2], 8); // ? d[i-4] ? d[i-5] + dat[1] = _mm_alignr_epi8(dat[0], dat[1], 8); // ? d[i-2] ? d[i-3] + dat[0] = _mm_alignr_epi8(temp, dat[0], 8); // ? d[i ] ? d[i-1] + + summ = _mm_mul_epi32(dat[5], qlp[5]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[4], qlp[4])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[3], qlp[3])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[2], qlp[2])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); // ?_64 sum_64 + summ = _mm_srl_epi64(summ, cnt); // ?_64 (sum >> lp_quantization)_64 == ?_32 ?_32 ?_32 (sum >> lp_quantization)_32 + temp = _mm_cvtsi32_si128(residual[i]); // 0 0 0 r[i] + temp = _mm_add_epi32(temp, summ); // ? ? ? d[i] + data[i] = _mm_cvtsi128_si32(temp); + } + } + else { /* order == 9, 10 */ + __m128i qlp[5], dat[5]; + __m128i summ, temp; + qlp[0] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + qlp[1] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + qlp[2] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + qlp[3] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + if (order == 10) + qlp[4] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); + else + qlp[4] = _mm_cvtsi32_si128(qlp_coeff[8]); + + qlp[0] = _mm_shuffle_epi32(qlp[0], _MM_SHUFFLE(2,0,3,1)); + qlp[1] = _mm_shuffle_epi32(qlp[1], _MM_SHUFFLE(2,0,3,1)); + qlp[2] = _mm_shuffle_epi32(qlp[2], _MM_SHUFFLE(2,0,3,1)); + qlp[3] = _mm_shuffle_epi32(qlp[3], _MM_SHUFFLE(2,0,3,1)); + qlp[4] = _mm_shuffle_epi32(qlp[4], _MM_SHUFFLE(2,0,3,1)); + + dat[4] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-10))); + dat[3] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-8 ))); + dat[2] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-6 ))); + dat[1] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-4 ))); + dat[0] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-2 ))); + + summ = _mm_mul_epi32(dat[4], qlp[4]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[3], qlp[3])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[2], qlp[2])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[0]); + temp = _mm_add_epi32(temp, summ); + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + dat[4] = _mm_alignr_epi8(dat[3], dat[4], 8); + dat[3] = _mm_alignr_epi8(dat[2], dat[3], 8); + dat[2] = _mm_alignr_epi8(dat[1], dat[2], 8); + dat[1] = _mm_alignr_epi8(dat[0], dat[1], 8); + dat[0] = _mm_alignr_epi8(temp, dat[0], 8); + + summ = _mm_mul_epi32(dat[4], qlp[4]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[3], qlp[3])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[2], qlp[2])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[i]); + temp = _mm_add_epi32(temp, summ); + data[i] = _mm_cvtsi128_si32(temp); + } + } + } + else if(order > 4) { /* order == 5, 6, 7, 8 */ + if(order > 6) { /* order == 7, 8 */ + __m128i qlp[4], dat[4]; + __m128i summ, temp; + qlp[0] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + qlp[1] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + qlp[2] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + if (order == 8) + qlp[3] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); + else + qlp[3] = _mm_cvtsi32_si128(qlp_coeff[6]); + + qlp[0] = _mm_shuffle_epi32(qlp[0], _MM_SHUFFLE(2,0,3,1)); + qlp[1] = _mm_shuffle_epi32(qlp[1], _MM_SHUFFLE(2,0,3,1)); + qlp[2] = _mm_shuffle_epi32(qlp[2], _MM_SHUFFLE(2,0,3,1)); + qlp[3] = _mm_shuffle_epi32(qlp[3], _MM_SHUFFLE(2,0,3,1)); + + dat[3] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-8 ))); + dat[2] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-6 ))); + dat[1] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-4 ))); + dat[0] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-2 ))); + + summ = _mm_mul_epi32(dat[3], qlp[3]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[2], qlp[2])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[0]); + temp = _mm_add_epi32(temp, summ); + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + dat[3] = _mm_alignr_epi8(dat[2], dat[3], 8); + dat[2] = _mm_alignr_epi8(dat[1], dat[2], 8); + dat[1] = _mm_alignr_epi8(dat[0], dat[1], 8); + dat[0] = _mm_alignr_epi8(temp, dat[0], 8); + + summ = _mm_mul_epi32(dat[3], qlp[3]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[2], qlp[2])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[i]); + temp = _mm_add_epi32(temp, summ); + data[i] = _mm_cvtsi128_si32(temp); + } + } + else { /* order == 5, 6 */ + __m128i qlp[3], dat[3]; + __m128i summ, temp; + qlp[0] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + qlp[1] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + if (order == 6) + qlp[2] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); + else + qlp[2] = _mm_cvtsi32_si128(qlp_coeff[4]); + + qlp[0] = _mm_shuffle_epi32(qlp[0], _MM_SHUFFLE(2,0,3,1)); + qlp[1] = _mm_shuffle_epi32(qlp[1], _MM_SHUFFLE(2,0,3,1)); + qlp[2] = _mm_shuffle_epi32(qlp[2], _MM_SHUFFLE(2,0,3,1)); + + dat[2] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-6 ))); + dat[1] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-4 ))); + dat[0] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-2 ))); + + summ = _mm_mul_epi32(dat[2], qlp[2]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[0]); + temp = _mm_add_epi32(temp, summ); + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + dat[2] = _mm_alignr_epi8(dat[1], dat[2], 8); + dat[1] = _mm_alignr_epi8(dat[0], dat[1], 8); + dat[0] = _mm_alignr_epi8(temp, dat[0], 8); + + summ = _mm_mul_epi32(dat[2], qlp[2]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[1], qlp[1])); + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[i]); + temp = _mm_add_epi32(temp, summ); + data[i] = _mm_cvtsi128_si32(temp); + } + } + } + else { /* order == 1, 2, 3, 4 */ + if(order > 2) { /* order == 3, 4 */ + __m128i qlp[2], dat[2]; + __m128i summ, temp; + qlp[0] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); + if (order == 4) + qlp[1] = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); + else + qlp[1] = _mm_cvtsi32_si128(qlp_coeff[2]); + + qlp[0] = _mm_shuffle_epi32(qlp[0], _MM_SHUFFLE(2,0,3,1)); + qlp[1] = _mm_shuffle_epi32(qlp[1], _MM_SHUFFLE(2,0,3,1)); + + dat[1] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-4 ))); + dat[0] = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-2 ))); + + summ = _mm_mul_epi32(dat[1], qlp[1]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[0]); + temp = _mm_add_epi32(temp, summ); + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + dat[1] = _mm_alignr_epi8(dat[0], dat[1], 8); + dat[0] = _mm_alignr_epi8(temp, dat[0], 8); + + summ = _mm_mul_epi32(dat[1], qlp[1]) ; + summ = _mm_add_epi64(summ, _mm_mul_epi32(dat[0], qlp[0])); + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[i]); + temp = _mm_add_epi32(temp, summ); + data[i] = _mm_cvtsi128_si32(temp); + } + } + else { /* order == 1, 2 */ + if(order == 2) { + __m128i qlp0, dat0; + __m128i summ, temp; + qlp0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff)); + qlp0 = _mm_shuffle_epi32(qlp0, _MM_SHUFFLE(2,0,3,1)); + + dat0 = _mm_cvtepu32_epi64(_mm_loadl_epi64((const __m128i*)(data-2 ))); + + summ = _mm_mul_epi32(dat0, qlp0) ; + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[0]); + temp = _mm_add_epi32(temp, summ); + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + dat0 = _mm_alignr_epi8(temp, dat0, 8); + + summ = _mm_mul_epi32(dat0, qlp0) ; + + summ = _mm_add_epi64(summ, _mm_srli_si128(summ, 8)); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[i]); + temp = _mm_add_epi32(temp, summ); + data[i] = _mm_cvtsi128_si32(temp); + } + } + else { /* order == 1 */ + __m128i qlp0; + __m128i summ, temp; + qlp0 = _mm_cvtsi32_si128(qlp_coeff[0]); + temp = _mm_cvtsi32_si128(data[-1]); + + summ = _mm_mul_epi32(temp, qlp0); + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[0]); + temp = _mm_add_epi32(temp, summ); + data[0] = _mm_cvtsi128_si32(temp); + + for(i = 1; i < (int)data_len; i++) { + summ = _mm_mul_epi32(temp, qlp0) ; + summ = _mm_srl_epi64(summ, cnt); + temp = _mm_cvtsi32_si128(residual[i]); + temp = _mm_add_epi32(temp, summ); + data[i] = _mm_cvtsi128_si32(temp); + } + } + } + } + } + else { /* order > 12 */ + FLAC__int64 sum; + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization); + } + } +} + +#endif /* defined FLAC__CPU_IA32 */ + +FLAC__SSE_TARGET("sse4.1") +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + FLAC__int32 sum; + __m128i cnt = _mm_cvtsi32_si128(lp_quantization); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + q9 = _mm_cvtsi32_si128(qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); + q10 = _mm_cvtsi32_si128(qlp_coeff[10]); q10 = _mm_shuffle_epi32(q10, _MM_SHUFFLE(0,0,0,0)); + q11 = _mm_cvtsi32_si128(qlp_coeff[11]); q11 = _mm_shuffle_epi32(q11, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q11, _mm_loadu_si128((const __m128i*)(data+i-12))); + mull = _mm_mullo_epi32(q10, _mm_loadu_si128((const __m128i*)(data+i-11))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 11 */ + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + q9 = _mm_cvtsi32_si128(qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); + q10 = _mm_cvtsi32_si128(qlp_coeff[10]); q10 = _mm_shuffle_epi32(q10, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q10, _mm_loadu_si128((const __m128i*)(data+i-11))); + mull = _mm_mullo_epi32(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + else { + if(order == 10) { + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + q9 = _mm_cvtsi32_si128(qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); + mull = _mm_mullo_epi32(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 9 */ + __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + q8 = _mm_cvtsi32_si128(qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); + mull = _mm_mullo_epi32(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + __m128i q0, q1, q2, q3, q4, q5, q6, q7; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + q7 = _mm_cvtsi32_si128(qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); + mull = _mm_mullo_epi32(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 7 */ + __m128i q0, q1, q2, q3, q4, q5, q6; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + q6 = _mm_cvtsi32_si128(qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); + mull = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + else { + if(order == 6) { + __m128i q0, q1, q2, q3, q4, q5; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + q5 = _mm_cvtsi32_si128(qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); + mull = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 5 */ + __m128i q0, q1, q2, q3, q4; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + q4 = _mm_cvtsi32_si128(qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); + mull = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + __m128i q0, q1, q2, q3; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + q3 = _mm_cvtsi32_si128(qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); + mull = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 3 */ + __m128i q0, q1, q2; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + q2 = _mm_cvtsi32_si128(qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); + mull = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + else { + if(order == 2) { + __m128i q0, q1; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + q1 = _mm_cvtsi32_si128(qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ, mull; + summ = _mm_mullo_epi32(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); + mull = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + else { /* order == 1 */ + __m128i q0; + q0 = _mm_cvtsi32_si128(qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); + + for(i = 0; i < (int)data_len-3; i+=4) { + __m128i summ; + summ = _mm_mullo_epi32(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); + summ = _mm_sra_epi32(summ, cnt); + _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); + } + } + } + } + for(; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 12: sum += qlp_coeff[11] * data[i-12]; + case 11: sum += qlp_coeff[10] * data[i-11]; + case 10: sum += qlp_coeff[ 9] * data[i-10]; + case 9: sum += qlp_coeff[ 8] * data[i- 9]; + case 8: sum += qlp_coeff[ 7] * data[i- 8]; + case 7: sum += qlp_coeff[ 6] * data[i- 7]; + case 6: sum += qlp_coeff[ 5] * data[i- 6]; + case 5: sum += qlp_coeff[ 4] * data[i- 5]; + case 4: sum += qlp_coeff[ 3] * data[i- 4]; + case 3: sum += qlp_coeff[ 2] * data[i- 3]; + case 2: sum += qlp_coeff[ 1] * data[i- 2]; + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; + case 31: sum += qlp_coeff[30] * data[i-31]; + case 30: sum += qlp_coeff[29] * data[i-30]; + case 29: sum += qlp_coeff[28] * data[i-29]; + case 28: sum += qlp_coeff[27] * data[i-28]; + case 27: sum += qlp_coeff[26] * data[i-27]; + case 26: sum += qlp_coeff[25] * data[i-26]; + case 25: sum += qlp_coeff[24] * data[i-25]; + case 24: sum += qlp_coeff[23] * data[i-24]; + case 23: sum += qlp_coeff[22] * data[i-23]; + case 22: sum += qlp_coeff[21] * data[i-22]; + case 21: sum += qlp_coeff[20] * data[i-21]; + case 20: sum += qlp_coeff[19] * data[i-20]; + case 19: sum += qlp_coeff[18] * data[i-19]; + case 18: sum += qlp_coeff[17] * data[i-18]; + case 17: sum += qlp_coeff[16] * data[i-17]; + case 16: sum += qlp_coeff[15] * data[i-16]; + case 15: sum += qlp_coeff[14] * data[i-15]; + case 14: sum += qlp_coeff[13] * data[i-14]; + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } +} + +#endif /* FLAC__SSE4_1_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/md5.c b/deps/flac-1.3.2/src/libFLAC/md5.c new file mode 100644 index 0000000..e9013a9 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/md5.c @@ -0,0 +1,516 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> /* for malloc() */ +#include <string.h> /* for memcpy() */ + +#include "private/md5.h" +#include "share/alloc.h" +#include "share/endswap.h" + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' header + * definitions; now uses stuff from dpkg's config.h. + * - Ian Jackson <ijackson@nyx.cs.du.edu>. + * Still in the public domain. + * + * Josh Coalson: made some changes to integrate with libFLAC. + * Still in the public domain. + */ + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f,w,x,y,z,in,s) \ + (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) +{ + register FLAC__uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#if WORDS_BIGENDIAN +//@@@@@@ OPT: use bswap/intrinsics +static void byteSwap(FLAC__uint32 *buf, unsigned words) +{ + register FLAC__uint32 x; + do { + x = *buf; + x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); + *buf++ = (x >> 16) | (x << 16); + } while (--words); +} +static void byteSwapX16(FLAC__uint32 *buf) +{ + register FLAC__uint32 x; + + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16); +} +#else +#define byteSwap(buf, words) +#define byteSwapX16(buf) +#endif + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsigned len) +{ + FLAC__uint32 t; + + /* Update byte count */ + + t = ctx->bytes[0]; + if ((ctx->bytes[0] = t + len) < t) + ctx->bytes[1]++; /* Carry from low to high */ + + t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ + if (t > len) { + memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len); + return; + } + /* First chunk is an odd size */ + memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t); + byteSwapX16(ctx->in); + FLAC__MD5Transform(ctx->buf, ctx->in); + buf += t; + len -= t; + + /* Process data in 64-byte chunks */ + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteSwapX16(ctx->in); + FLAC__MD5Transform(ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void FLAC__MD5Init(FLAC__MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; + + ctx->internal_buf.p8 = 0; + ctx->capacity = 0; +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) +{ + int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ + FLAC__byte *p = (FLAC__byte *)ctx->in + count; + + /* Set the first char of padding to 0x80. There is always room. */ + *p++ = 0x80; + + /* Bytes of padding needed to make 56 bytes (-8..55) */ + count = 56 - 1 - count; + + if (count < 0) { /* Padding forces an extra block */ + memset(p, 0, count + 8); + byteSwapX16(ctx->in); + FLAC__MD5Transform(ctx->buf, ctx->in); + p = (FLAC__byte *)ctx->in; + count = 56; + } + memset(p, 0, count); + byteSwap(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in[14] = ctx->bytes[0] << 3; + ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; + FLAC__MD5Transform(ctx->buf, ctx->in); + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + if (0 != ctx->internal_buf.p8) { + free(ctx->internal_buf.p8); + ctx->internal_buf.p8 = 0; + ctx->capacity = 0; + } + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +/* + * Convert the incoming audio signal to a byte stream + */ +static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) +{ + FLAC__byte *buf_ = mbuf->p8; + FLAC__int16 *buf16 = mbuf->p16; + FLAC__int32 *buf32 = mbuf->p32; + FLAC__int32 a_word; + unsigned channel, sample; + + /* Storage in the output buffer, buf, is little endian. */ + +#define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels) + + /* First do the most commonly used combinations. */ + switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) { + /* One byte per sample. */ + case (BYTES_CHANNEL_SELECTOR (1, 1)): + for (sample = 0; sample < samples; sample++) + *buf_++ = signal[0][sample]; + return; + + case (BYTES_CHANNEL_SELECTOR (1, 2)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR (1, 4)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR (1, 6)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + *buf_++ = signal[4][sample]; + *buf_++ = signal[5][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR (1, 8)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + *buf_++ = signal[4][sample]; + *buf_++ = signal[5][sample]; + *buf_++ = signal[6][sample]; + *buf_++ = signal[7][sample]; + } + return; + + /* Two bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR (2, 1)): + for (sample = 0; sample < samples; sample++) + *buf16++ = H2LE_16(signal[0][sample]); + return; + + case (BYTES_CHANNEL_SELECTOR (2, 2)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (2, 4)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (2, 6)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + *buf16++ = H2LE_16(signal[4][sample]); + *buf16++ = H2LE_16(signal[5][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (2, 8)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + *buf16++ = H2LE_16(signal[4][sample]); + *buf16++ = H2LE_16(signal[5][sample]); + *buf16++ = H2LE_16(signal[6][sample]); + *buf16++ = H2LE_16(signal[7][sample]); + } + return; + + /* Three bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR (3, 1)): + for (sample = 0; sample < samples; sample++) { + a_word = signal[0][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + } + return; + + case (BYTES_CHANNEL_SELECTOR (3, 2)): + for (sample = 0; sample < samples; sample++) { + a_word = signal[0][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + a_word = signal[1][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + } + return; + + /* Four bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR (4, 1)): + for (sample = 0; sample < samples; sample++) + *buf32++ = H2LE_32(signal[0][sample]); + return; + + case (BYTES_CHANNEL_SELECTOR (4, 2)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (4, 4)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (4, 6)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + *buf32++ = H2LE_32(signal[4][sample]); + *buf32++ = H2LE_32(signal[5][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (4, 8)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + *buf32++ = H2LE_32(signal[4][sample]); + *buf32++ = H2LE_32(signal[5][sample]); + *buf32++ = H2LE_32(signal[6][sample]); + *buf32++ = H2LE_32(signal[7][sample]); + } + return; + + default: + break; + } + + /* General version. */ + switch (bytes_per_sample) { + case 1: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) + *buf_++ = signal[channel][sample]; + return; + + case 2: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) + *buf16++ = H2LE_16(signal[channel][sample]); + return; + + case 3: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) { + a_word = signal[channel][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + } + return; + + case 4: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) + *buf32++ = H2LE_32(signal[channel][sample]); + return; + + default: + break; + } +} + +/* + * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. + */ +FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) +{ + const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; + + /* overflow check */ + if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) + return false; + if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) + return false; + + if (ctx->capacity < bytes_needed) { + if (0 == (ctx->internal_buf.p8 = safe_realloc_(ctx->internal_buf.p8, bytes_needed))) { + if (0 == (ctx->internal_buf.p8 = safe_malloc_(bytes_needed))) { + ctx->capacity = 0; + return false; + } + } + ctx->capacity = bytes_needed; + } + + format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample); + + FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed); + + return true; +} diff --git a/deps/flac-1.3.2/src/libFLAC/memory.c b/deps/flac-1.3.2/src/libFLAC/memory.c new file mode 100644 index 0000000..a8ebd10 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/memory.c @@ -0,0 +1,218 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#include "private/memory.h" +#include "FLAC/assert.h" +#include "share/alloc.h" + +void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) +{ + void *x; + + FLAC__ASSERT(0 != aligned_address); + +#ifdef FLAC__ALIGN_MALLOC_DATA + /* align on 32-byte (256-bit) boundary */ + x = safe_malloc_add_2op_(bytes, /*+*/31L); + *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); +#else + x = safe_malloc_(bytes); + *aligned_address = x; +#endif + return x; +} + +FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) +{ + FLAC__int32 *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__int32 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if(0 == pu) { + return false; + } + else { + if(*unaligned_pointer != 0) + free(*unaligned_pointer); + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } +} + +FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) +{ + FLAC__uint32 *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__uint32 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if(0 == pu) { + return false; + } + else { + if(*unaligned_pointer != 0) + free(*unaligned_pointer); + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } +} + +FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) +{ + FLAC__uint64 *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__uint64 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if(0 == pu) { + return false; + } + else { + if(*unaligned_pointer != 0) + free(*unaligned_pointer); + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } +} + +FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer) +{ + unsigned *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + unsigned *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if(0 == pu) { + return false; + } + else { + if(*unaligned_pointer != 0) + free(*unaligned_pointer); + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } +} + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + +FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) +{ + FLAC__real *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__real *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if(0 == pu) { + return false; + } + else { + if(*unaligned_pointer != 0) + free(*unaligned_pointer); + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } +} + +#endif + +void *safe_malloc_mul_2op_p(size_t size1, size_t size2) +{ + if(!size1 || !size2) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(size1 > SIZE_MAX / size2) + return 0; + return malloc(size1*size2); +} diff --git a/deps/flac-1.3.2/src/libFLAC/metadata_iterators.c b/deps/flac-1.3.2/src/libFLAC/metadata_iterators.c new file mode 100644 index 0000000..0a84d03 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/metadata_iterators.c @@ -0,0 +1,3481 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include <sys/stat.h> /* for stat(), maybe chmod() */ + +#include "private/metadata.h" + +#include "FLAC/assert.h" +#include "FLAC/stream_decoder.h" +#include "share/alloc.h" +#include "share/compat.h" +#include "share/macros.h" +#include "share/safe_str.h" +#include "private/macros.h" +#include "private/memory.h" + +/* Alias the first (in share/alloc.h) to the second (in src/libFLAC/memory.c). */ +#define safe_malloc_mul_2op_ safe_malloc_mul_2op_p + +/**************************************************************************** + * + * Local function declarations + * + ***************************************************************************/ + +static void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes); +static void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes); +static void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes); +static FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes); +static FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes); +static FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes); + +static FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator); +static FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block); +static FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry, unsigned max_length); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_VorbisComment *block, unsigned block_length); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Picture *block); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length); + +static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); +static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); +static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block); +static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block); +static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block); +static FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length); +static FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length); +static FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block); +static FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block); +static FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block); +static FLAC__bool write_metadata_block_data_picture_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Picture *block); +static FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length); + +static FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block); +static FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last); +static FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append); + +static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator); +static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator); + +static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb); +static unsigned seek_to_first_metadata_block_(FILE *f); + +static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append); +static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, FLAC__off_t fixup_is_last_flag_offset, FLAC__bool backup); + +static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); +static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); +static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status); +static FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status); + +static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status); +static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status); +static void cleanup_tempfile_(FILE **tempfile, char **tempfilename); + +static FLAC__bool get_file_stats_(const char *filename, struct flac_stat_s *stats); +static void set_file_stats_(const char *filename, struct flac_stat_s *stats); + +static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence); +static FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle); + +static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status); + + +#ifdef FLAC__VALGRIND_TESTING +static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t ret = fwrite(ptr, size, nmemb, stream); + if(!ferror(stream)) + fflush(stream); + return ret; +} +#else +#define local__fwrite fwrite +#endif + +/**************************************************************************** + * + * Level 0 implementation + * + ***************************************************************************/ + +static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); +static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); +static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); + +typedef struct { + FLAC__bool got_error; + FLAC__StreamMetadata *object; +} level0_client_data; + +static FLAC__StreamMetadata *get_one_metadata_block_(const char *filename, FLAC__MetadataType type) +{ + level0_client_data cd; + FLAC__StreamDecoder *decoder; + + FLAC__ASSERT(0 != filename); + + cd.got_error = false; + cd.object = 0; + + decoder = FLAC__stream_decoder_new(); + + if(0 == decoder) + return 0; + + FLAC__stream_decoder_set_md5_checking(decoder, false); + FLAC__stream_decoder_set_metadata_ignore_all(decoder); + FLAC__stream_decoder_set_metadata_respond(decoder, type); + + if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &cd) != FLAC__STREAM_DECODER_INIT_STATUS_OK || cd.got_error) { + (void)FLAC__stream_decoder_finish(decoder); + FLAC__stream_decoder_delete(decoder); + return 0; + } + + if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder) || cd.got_error) { + (void)FLAC__stream_decoder_finish(decoder); + FLAC__stream_decoder_delete(decoder); + if(0 != cd.object) + FLAC__metadata_object_delete(cd.object); + return 0; + } + + (void)FLAC__stream_decoder_finish(decoder); + FLAC__stream_decoder_delete(decoder); + + return cd.object; +} + +FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo) +{ + FLAC__StreamMetadata *object; + + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != streaminfo); + + object = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_STREAMINFO); + + if (object) { + /* can just copy the contents since STREAMINFO has no internal structure */ + *streaminfo = *object; + FLAC__metadata_object_delete(object); + return true; + } + else { + return false; + } +} + +FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags) +{ + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != tags); + + *tags = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_VORBIS_COMMENT); + + return 0 != *tags; +} + +FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet) +{ + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != cuesheet); + + *cuesheet = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_CUESHEET); + + return 0 != *cuesheet; +} + +FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) +{ + (void)decoder, (void)frame, (void)buffer, (void)client_data; + + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; +} + +void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + level0_client_data *cd = (level0_client_data *)client_data; + (void)decoder; + + /* + * we assume we only get here when the one metadata block we were + * looking for was passed to us + */ + if(!cd->got_error && 0 == cd->object) { + if(0 == (cd->object = FLAC__metadata_object_clone(metadata))) + cd->got_error = true; + } +} + +void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + level0_client_data *cd = (level0_client_data *)client_data; + (void)decoder; + + if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) + cd->got_error = true; +} + +FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors) +{ + FLAC__Metadata_SimpleIterator *it; + FLAC__uint64 max_area_seen = 0; + FLAC__uint64 max_depth_seen = 0; + + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != picture); + + *picture = 0; + + it = FLAC__metadata_simple_iterator_new(); + if(0 == it) + return false; + if(!FLAC__metadata_simple_iterator_init(it, filename, /*read_only=*/true, /*preserve_file_stats=*/true)) { + FLAC__metadata_simple_iterator_delete(it); + return false; + } + do { + if(FLAC__metadata_simple_iterator_get_block_type(it) == FLAC__METADATA_TYPE_PICTURE) { + FLAC__StreamMetadata *obj = FLAC__metadata_simple_iterator_get_block(it); + FLAC__uint64 area = (FLAC__uint64)obj->data.picture.width * (FLAC__uint64)obj->data.picture.height; + /* check constraints */ + if( + (type == (FLAC__StreamMetadata_Picture_Type)(-1) || type == obj->data.picture.type) && + (mime_type == 0 || !strcmp(mime_type, obj->data.picture.mime_type)) && + (description == 0 || !strcmp((const char *)description, (const char *)obj->data.picture.description)) && + obj->data.picture.width <= max_width && + obj->data.picture.height <= max_height && + obj->data.picture.depth <= max_depth && + obj->data.picture.colors <= max_colors && + (area > max_area_seen || (area == max_area_seen && obj->data.picture.depth > max_depth_seen)) + ) { + if(*picture) + FLAC__metadata_object_delete(*picture); + *picture = obj; + max_area_seen = area; + max_depth_seen = obj->data.picture.depth; + } + else { + FLAC__metadata_object_delete(obj); + } + } + } while(FLAC__metadata_simple_iterator_next(it)); + + FLAC__metadata_simple_iterator_delete(it); + + return (0 != *picture); +} + + +/**************************************************************************** + * + * Level 1 implementation + * + ***************************************************************************/ + +#define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4) +/* 1 for initial offset, +4 for our own personal use */ + +struct FLAC__Metadata_SimpleIterator { + FILE *file; + char *filename, *tempfile_path_prefix; + struct flac_stat_s stats; + FLAC__bool has_stats; + FLAC__bool is_writable; + FLAC__Metadata_SimpleIteratorStatus status; + FLAC__off_t offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH]; + FLAC__off_t first_offset; /* this is the offset to the STREAMINFO block */ + unsigned depth; + /* this is the metadata block header of the current block we are pointing to: */ + FLAC__bool is_last; + FLAC__MetadataType type; + unsigned length; +}; + +FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[] = { + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR", + "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR" +}; + + +FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void) +{ + FLAC__Metadata_SimpleIterator *iterator = calloc(1, sizeof(FLAC__Metadata_SimpleIterator)); + + if(0 != iterator) { + iterator->file = 0; + iterator->filename = 0; + iterator->tempfile_path_prefix = 0; + iterator->has_stats = false; + iterator->is_writable = false; + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; + iterator->first_offset = iterator->offset[0] = -1; + iterator->depth = 0; + } + + return iterator; +} + +static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + + if(0 != iterator->file) { + fclose(iterator->file); + iterator->file = 0; + if(iterator->has_stats) + set_file_stats_(iterator->filename, &iterator->stats); + } + if(0 != iterator->filename) { + free(iterator->filename); + iterator->filename = 0; + } + if(0 != iterator->tempfile_path_prefix) { + free(iterator->tempfile_path_prefix); + iterator->tempfile_path_prefix = 0; + } +} + +FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + + simple_iterator_free_guts_(iterator); + free(iterator); +} + +FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__Metadata_SimpleIteratorStatus status; + + FLAC__ASSERT(0 != iterator); + + status = iterator->status; + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; + return status; +} + +static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool read_only) +{ + unsigned ret; + + FLAC__ASSERT(0 != iterator); + + if(read_only || 0 == (iterator->file = flac_fopen(iterator->filename, "r+b"))) { + iterator->is_writable = false; + if(read_only || errno == EACCES) { + if(0 == (iterator->file = flac_fopen(iterator->filename, "rb"))) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; + return false; + } + } + else { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; + return false; + } + } + else { + iterator->is_writable = true; + } + + ret = seek_to_first_metadata_block_(iterator->file); + switch(ret) { + case 0: + iterator->depth = 0; + iterator->first_offset = iterator->offset[iterator->depth] = ftello(iterator->file); + return read_metadata_block_header_(iterator); + case 1: + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + case 2: + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + case 3: + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE; + return false; + default: + FLAC__ASSERT(0); + return false; + } +} + +#if 0 +@@@ If we decide to finish implementing this, put this comment back in metadata.h +/* + * The 'tempfile_path_prefix' allows you to specify a directory where + * tempfiles should go. Remember that if your metadata edits cause the + * FLAC file to grow, the entire file will have to be rewritten. If + * 'tempfile_path_prefix' is NULL, the temp file will be written in the + * same directory as the original FLAC file. This makes replacing the + * original with the tempfile fast but requires extra space in the same + * partition for the tempfile. If space is a problem, you can pass a + * directory name belonging to a different partition in + * 'tempfile_path_prefix'. Note that you should use the forward slash + * '/' as the directory separator. A trailing slash is not needed; it + * will be added automatically. + */ +FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats, const char *tempfile_path_prefix); +#endif + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats) +{ + const char *tempfile_path_prefix = 0; /*@@@ search for comments near 'flac_rename(...)' for what it will take to finish implementing this */ + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != filename); + + simple_iterator_free_guts_(iterator); + + if(!read_only && preserve_file_stats) + iterator->has_stats = get_file_stats_(filename, &iterator->stats); + + if(0 == (iterator->filename = strdup(filename))) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + if(0 != tempfile_path_prefix && 0 == (iterator->tempfile_path_prefix = strdup(tempfile_path_prefix))) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + + return simple_iterator_prime_input_(iterator, read_only); +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->is_writable; +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + if(iterator->is_last) + return false; + + if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + iterator->offset[iterator->depth] = ftello(iterator->file); + + return read_metadata_block_header_(iterator); +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__off_t this_offset; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + if(iterator->offset[iterator->depth] == iterator->first_offset) + return false; + + if(0 != fseeko(iterator->file, iterator->first_offset, SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + this_offset = iterator->first_offset; + if(!read_metadata_block_header_(iterator)) + return false; + + /* we ignore any error from ftello() and catch it in fseeko() */ + while(ftello(iterator->file) + (FLAC__off_t)iterator->length < iterator->offset[iterator->depth]) { + if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + this_offset = ftello(iterator->file); + if(!read_metadata_block_header_(iterator)) + return false; + } + + iterator->offset[iterator->depth] = this_offset; + + return true; +} + +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->is_last; +} + +/*@@@@add to tests*/ +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->offset[iterator->depth]; +} + +FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->type; +} + +/*@@@@add to tests*/ +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->length; +} + +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id) +{ + const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + FLAC__ASSERT(0 != id); + + if(iterator->type != FLAC__METADATA_TYPE_APPLICATION) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; + return false; + } + + if(fread(id, 1, id_bytes, iterator->file) != id_bytes) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + + /* back up */ + if(0 != fseeko(iterator->file, -((int)id_bytes), SEEK_CUR)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + return true; +} + +FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type); + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + if(0 != block) { + block->is_last = iterator->is_last; + block->length = iterator->length; + + if(!read_metadata_block_data_(iterator, block)) { + FLAC__metadata_object_delete(block); + return 0; + } + + /* back up to the beginning of the block data to stay consistent */ + if(0 != fseeko(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + FLAC__metadata_object_delete(block); + return 0; + } + } + else + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + return block; +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding) +{ + FLAC__ASSERT_DECLARATION(FLAC__off_t debug_target_offset = iterator->offset[iterator->depth];) + FLAC__bool ret; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + FLAC__ASSERT(0 != block); + + if(!iterator->is_writable) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE; + return false; + } + + if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO || block->type == FLAC__METADATA_TYPE_STREAMINFO) { + if(iterator->type != block->type) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; + return false; + } + } + + block->is_last = iterator->is_last; + + if(iterator->length == block->length) + return write_metadata_block_stationary_(iterator, block); + else if(iterator->length > block->length) { + if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) { + ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last); + FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + else { + ret = rewrite_whole_file_(iterator, block, /*append=*/false); + FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + } + else /* iterator->length < block->length */ { + unsigned padding_leftover = 0; + FLAC__bool padding_is_last = false; + if(use_padding) { + /* first see if we can even use padding */ + if(iterator->is_last) { + use_padding = false; + } + else { + const unsigned extra_padding_bytes_required = block->length - iterator->length; + simple_iterator_push_(iterator); + if(!FLAC__metadata_simple_iterator_next(iterator)) { + (void)simple_iterator_pop_(iterator); + return false; + } + if(iterator->type != FLAC__METADATA_TYPE_PADDING) { + use_padding = false; + } + else { + if(FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length == extra_padding_bytes_required) { + padding_leftover = 0; + block->is_last = iterator->is_last; + } + else if(iterator->length < extra_padding_bytes_required) + use_padding = false; + else { + padding_leftover = FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length - extra_padding_bytes_required; + padding_is_last = iterator->is_last; + block->is_last = false; + } + } + if(!simple_iterator_pop_(iterator)) + return false; + } + } + if(use_padding) { + if(padding_leftover == 0) { + ret = write_metadata_block_stationary_(iterator, block); + FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + else { + FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); + ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); + FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + } + else { + ret = rewrite_whole_file_(iterator, block, /*append=*/false); + FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + } +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding) +{ + unsigned padding_leftover = 0; + FLAC__bool padding_is_last = false; + + FLAC__ASSERT_DECLARATION(FLAC__off_t debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;) + FLAC__bool ret; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + FLAC__ASSERT(0 != block); + + if(!iterator->is_writable) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE; + return false; + } + + if(block->type == FLAC__METADATA_TYPE_STREAMINFO) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; + return false; + } + + block->is_last = iterator->is_last; + + if(use_padding) { + /* first see if we can even use padding */ + if(iterator->is_last) { + use_padding = false; + } + else { + simple_iterator_push_(iterator); + if(!FLAC__metadata_simple_iterator_next(iterator)) { + (void)simple_iterator_pop_(iterator); + return false; + } + if(iterator->type != FLAC__METADATA_TYPE_PADDING) { + use_padding = false; + } + else { + if(iterator->length == block->length) { + padding_leftover = 0; + block->is_last = iterator->is_last; + } + else if(iterator->length < FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) + use_padding = false; + else { + padding_leftover = iterator->length - block->length; + padding_is_last = iterator->is_last; + block->is_last = false; + } + } + if(!simple_iterator_pop_(iterator)) + return false; + } + } + if(use_padding) { + /* move to the next block, which is suitable padding */ + if(!FLAC__metadata_simple_iterator_next(iterator)) + return false; + if(padding_leftover == 0) { + ret = write_metadata_block_stationary_(iterator, block); + FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + else { + FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); + ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); + FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } + } + else { + ret = rewrite_whole_file_(iterator, block, /*append=*/true); + FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + return ret; + } +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding) +{ + FLAC__ASSERT_DECLARATION(FLAC__off_t debug_target_offset = iterator->offset[iterator->depth];) + FLAC__bool ret; + + if(!iterator->is_writable) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE; + return false; + } + + if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; + return false; + } + + if(use_padding) { + FLAC__StreamMetadata *padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING); + if(0 == padding) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + padding->length = iterator->length; + if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false)) { + FLAC__metadata_object_delete(padding); + return false; + } + FLAC__metadata_object_delete(padding); + if(!FLAC__metadata_simple_iterator_prev(iterator)) + return false; + FLAC__ASSERT(iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) + (FLAC__off_t)iterator->length == debug_target_offset); + return true; + } + else { + ret = rewrite_whole_file_(iterator, 0, /*append=*/false); + FLAC__ASSERT(iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) + (FLAC__off_t)iterator->length == debug_target_offset); + return ret; + } +} + + + +/**************************************************************************** + * + * Level 2 implementation + * + ***************************************************************************/ + + +typedef struct FLAC__Metadata_Node { + FLAC__StreamMetadata *data; + struct FLAC__Metadata_Node *prev, *next; +} FLAC__Metadata_Node; + +struct FLAC__Metadata_Chain { + char *filename; /* will be NULL if using callbacks */ + FLAC__bool is_ogg; + FLAC__Metadata_Node *head; + FLAC__Metadata_Node *tail; + unsigned nodes; + FLAC__Metadata_ChainStatus status; + FLAC__off_t first_offset, last_offset; + /* + * This is the length of the chain initially read from the FLAC file. + * it is used to compare against the current length to decide whether + * or not the whole file has to be rewritten. + */ + FLAC__off_t initial_length; + /* @@@ hacky, these are currently only needed by ogg reader */ + FLAC__IOHandle handle; + FLAC__IOCallback_Read read_cb; +}; + +struct FLAC__Metadata_Iterator { + FLAC__Metadata_Chain *chain; + FLAC__Metadata_Node *current; +}; + +FLAC_API const char * const FLAC__Metadata_ChainStatusString[] = { + "FLAC__METADATA_CHAIN_STATUS_OK", + "FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT", + "FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE", + "FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE", + "FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE", + "FLAC__METADATA_CHAIN_STATUS_BAD_METADATA", + "FLAC__METADATA_CHAIN_STATUS_READ_ERROR", + "FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR", + "FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR", + "FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR", + "FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR", + "FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR", + "FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR", + "FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS", + "FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", + "FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL" +}; + + +static FLAC__Metadata_Node *node_new_(void) +{ + return calloc(1, sizeof(FLAC__Metadata_Node)); +} + +static void node_delete_(FLAC__Metadata_Node *node) +{ + FLAC__ASSERT(0 != node); + if(0 != node->data) + FLAC__metadata_object_delete(node->data); + free(node); +} + +static void chain_init_(FLAC__Metadata_Chain *chain) +{ + FLAC__ASSERT(0 != chain); + + chain->filename = 0; + chain->is_ogg = false; + chain->head = chain->tail = 0; + chain->nodes = 0; + chain->status = FLAC__METADATA_CHAIN_STATUS_OK; + chain->initial_length = 0; + chain->read_cb = 0; +} + +static void chain_clear_(FLAC__Metadata_Chain *chain) +{ + FLAC__Metadata_Node *node, *next; + + FLAC__ASSERT(0 != chain); + + for(node = chain->head; node; ) { + next = node->next; + node_delete_(node); + node = next; + } + + if(0 != chain->filename) + free(chain->filename); + + chain_init_(chain); +} + +static void chain_append_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) +{ + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 != node); + FLAC__ASSERT(0 != node->data); + + node->next = node->prev = 0; + node->data->is_last = true; + if(0 != chain->tail) + chain->tail->data->is_last = false; + + if(0 == chain->head) + chain->head = node; + else { + FLAC__ASSERT(0 != chain->tail); + chain->tail->next = node; + node->prev = chain->tail; + } + chain->tail = node; + chain->nodes++; +} + +static void chain_remove_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) +{ + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 != node); + + if(node == chain->head) + chain->head = node->next; + else + node->prev->next = node->next; + + if(node == chain->tail) + chain->tail = node->prev; + else + node->next->prev = node->prev; + + if(0 != chain->tail) + chain->tail->data->is_last = true; + + chain->nodes--; +} + +static void chain_delete_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) +{ + chain_remove_node_(chain, node); + node_delete_(node); +} + +static FLAC__off_t chain_calculate_length_(FLAC__Metadata_Chain *chain) +{ + const FLAC__Metadata_Node *node; + FLAC__off_t length = 0; + for(node = chain->head; node; node = node->next) + length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); + return length; +} + +static void iterator_insert_node_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node) +{ + FLAC__ASSERT(0 != node); + FLAC__ASSERT(0 != node->data); + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + FLAC__ASSERT(0 != iterator->chain); + FLAC__ASSERT(0 != iterator->chain->head); + FLAC__ASSERT(0 != iterator->chain->tail); + + node->data->is_last = false; + + node->prev = iterator->current->prev; + node->next = iterator->current; + + if(0 == node->prev) + iterator->chain->head = node; + else + node->prev->next = node; + + iterator->current->prev = node; + + iterator->chain->nodes++; +} + +static void iterator_insert_node_after_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node) +{ + FLAC__ASSERT(0 != node); + FLAC__ASSERT(0 != node->data); + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + FLAC__ASSERT(0 != iterator->chain); + FLAC__ASSERT(0 != iterator->chain->head); + FLAC__ASSERT(0 != iterator->chain->tail); + + iterator->current->data->is_last = false; + + node->prev = iterator->current; + node->next = iterator->current->next; + + if(0 == node->next) + iterator->chain->tail = node; + else + node->next->prev = node; + + node->prev->next = node; + + iterator->chain->tail->data->is_last = true; + + iterator->chain->nodes++; +} + +/* return true iff node and node->next are both padding */ +static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) +{ + if(node->data->type == FLAC__METADATA_TYPE_PADDING && 0 != node->next && node->next->data->type == FLAC__METADATA_TYPE_PADDING) { + const unsigned growth = FLAC__STREAM_METADATA_HEADER_LENGTH + node->next->data->length; + node->data->length += growth; /* new block size can be greater than max metadata block size, but it'll be fixed later in chain_prepare_for_write_() */ + + chain_delete_node_(chain, node->next); + return true; + } + else + return false; +} + +/* Returns the new length of the chain, or 0 if there was an error. */ +/* WATCHOUT: This can get called multiple times before a write, so + * it should still work when this happens. + */ +/* WATCHOUT: Make sure to also update the logic in + * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes. + */ +static FLAC__off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding) +{ + FLAC__off_t current_length = chain_calculate_length_(chain); + + if(use_padding) { + /* if the metadata shrank and the last block is padding, we just extend the last padding block */ + if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { + const FLAC__off_t delta = chain->initial_length - current_length; + chain->tail->data->length += delta; + current_length += delta; + FLAC__ASSERT(current_length == chain->initial_length); + } + /* if the metadata shrank more than 4 bytes then there's room to add another padding block */ + else if(current_length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) { + FLAC__StreamMetadata *padding; + FLAC__Metadata_Node *node; + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return 0; + } + padding->length = chain->initial_length - (FLAC__STREAM_METADATA_HEADER_LENGTH + current_length); + if(0 == (node = node_new_())) { + FLAC__metadata_object_delete(padding); + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return 0; + } + node->data = padding; + chain_append_node_(chain, node); + current_length = chain_calculate_length_(chain); + FLAC__ASSERT(current_length == chain->initial_length); + } + /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */ + else if(current_length > chain->initial_length) { + const FLAC__off_t delta = current_length - chain->initial_length; + if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { + /* if the delta is exactly the size of the last padding block, remove the padding block */ + if((FLAC__off_t)chain->tail->data->length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) { + chain_delete_node_(chain, chain->tail); + current_length = chain_calculate_length_(chain); + FLAC__ASSERT(current_length == chain->initial_length); + } + /* if there is at least 'delta' bytes of padding, trim the padding down */ + else if((FLAC__off_t)chain->tail->data->length >= delta) { + chain->tail->data->length -= delta; + current_length -= delta; + FLAC__ASSERT(current_length == chain->initial_length); + } + } + } + } + + /* check sizes of all metadata blocks; reduce padding size if necessary */ + { + FLAC__Metadata_Node *node; + for (node = chain->head; node; node = node->next) { + if(node->data->length >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) { + if(node->data->type == FLAC__METADATA_TYPE_PADDING) { + node->data->length = (1u << FLAC__STREAM_METADATA_LENGTH_LEN) - 1; + current_length = chain_calculate_length_(chain); + } else { + chain->status = FLAC__METADATA_CHAIN_STATUS_BAD_METADATA; + return 0; + } + } + } + } + + return current_length; +} + +static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Tell tell_cb) +{ + FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != chain); + + /* we assume we're already at the beginning of the file */ + + switch(seek_to_first_metadata_block_cb_(handle, read_cb, seek_cb)) { + case 0: + break; + case 1: + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; + return false; + case 2: + chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + return false; + case 3: + chain->status = FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE; + return false; + default: + FLAC__ASSERT(0); + return false; + } + + { + FLAC__int64 pos = tell_cb(handle); + if(pos < 0) { + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; + return false; + } + chain->first_offset = (FLAC__off_t)pos; + } + + { + FLAC__bool is_last; + FLAC__MetadataType type; + unsigned length; + + do { + node = node_new_(); + if(0 == node) { + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + + if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) { + node_delete_(node); + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; + return false; + } + + node->data = FLAC__metadata_object_new(type); + if(0 == node->data) { + node_delete_(node); + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + + node->data->is_last = is_last; + node->data->length = length; + + chain->status = get_equivalent_status_(read_metadata_block_data_cb_(handle, read_cb, seek_cb, node->data)); + if(chain->status != FLAC__METADATA_CHAIN_STATUS_OK) { + node_delete_(node); + return false; + } + chain_append_node_(chain, node); + } while(!is_last); + } + + { + FLAC__int64 pos = tell_cb(handle); + if(pos < 0) { + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; + return false; + } + chain->last_offset = (FLAC__off_t)pos; + } + + chain->initial_length = chain_calculate_length_(chain); + + return true; +} + +static FLAC__StreamDecoderReadStatus chain_read_ogg_read_cb_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) +{ + FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)client_data; + (void)decoder; + if(*bytes > 0 && chain->status == FLAC__METADATA_CHAIN_STATUS_OK) { + *bytes = chain->read_cb(buffer, sizeof(FLAC__byte), *bytes, chain->handle); + if(*bytes == 0) + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + else + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + else + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; +} + +static FLAC__StreamDecoderWriteStatus chain_read_ogg_write_cb_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) +{ + (void)decoder, (void)frame, (void)buffer, (void)client_data; + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; +} + +static void chain_read_ogg_metadata_cb_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)client_data; + FLAC__Metadata_Node *node; + + (void)decoder; + + node = node_new_(); + if(0 == node) { + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return; + } + + node->data = FLAC__metadata_object_clone(metadata); + if(0 == node->data) { + node_delete_(node); + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return; + } + + chain_append_node_(chain, node); +} + +static void chain_read_ogg_error_cb_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)client_data; + (void)decoder, (void)status; + chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; /*@@@ maybe needs better error code */ +} + +static FLAC__bool chain_read_ogg_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb) +{ + FLAC__StreamDecoder *decoder; + + FLAC__ASSERT(0 != chain); + + /* we assume we're already at the beginning of the file */ + + chain->handle = handle; + chain->read_cb = read_cb; + if(0 == (decoder = FLAC__stream_decoder_new())) { + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + FLAC__stream_decoder_set_metadata_respond_all(decoder); + if(FLAC__stream_decoder_init_ogg_stream(decoder, chain_read_ogg_read_cb_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, chain_read_ogg_write_cb_, chain_read_ogg_metadata_cb_, chain_read_ogg_error_cb_, chain) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { + FLAC__stream_decoder_delete(decoder); + chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; /*@@@ maybe needs better error code */ + return false; + } + + chain->first_offset = 0; /*@@@ wrong; will need to be set correctly to implement metadata writing for Ogg FLAC */ + + if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) + chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; /*@@@ maybe needs better error code */ + if(chain->status != FLAC__METADATA_CHAIN_STATUS_OK) { + FLAC__stream_decoder_delete(decoder); + return false; + } + + FLAC__stream_decoder_delete(decoder); + + chain->last_offset = 0; /*@@@ wrong; will need to be set correctly to implement metadata writing for Ogg FLAC */ + + chain->initial_length = chain_calculate_length_(chain); + + return true; +} + +static FLAC__bool chain_rewrite_metadata_in_place_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, FLAC__IOCallback_Seek seek_cb) +{ + FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 != chain->head); + + if(0 != seek_cb(handle, chain->first_offset, SEEK_SET)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + return false; + } + + for(node = chain->head; node; node = node->next) { + if(!write_metadata_block_header_cb_(handle, write_cb, node->data)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; + return false; + } + if(!write_metadata_block_data_cb_(handle, write_cb, node->data)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; + return false; + } + } + + /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/ + + chain->status = FLAC__METADATA_CHAIN_STATUS_OK; + return true; +} + +static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain) +{ + FILE *file; + FLAC__bool ret; + + FLAC__ASSERT(0 != chain->filename); + + if(0 == (file = flac_fopen(chain->filename, "r+b"))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + return false; + } + + /* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */ + ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, fseek_wrapper_); + + fclose(file); + + return ret; +} + +static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix) +{ + FILE *f, *tempfile = NULL; + char *tempfilename; + FLAC__Metadata_SimpleIteratorStatus status; + const FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 != chain->filename); + FLAC__ASSERT(0 != chain->head); + + /* copy the file prefix (data up to first metadata block */ + if(0 == (f = flac_fopen(chain->filename, "rb"))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + return false; + } + if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) { + chain->status = get_equivalent_status_(status); + goto err; + } + if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) { + chain->status = get_equivalent_status_(status); + goto err; + } + + /* write the metadata */ + for(node = chain->head; node; node = node->next) { + if(!write_metadata_block_header_(tempfile, &status, node->data)) { + chain->status = get_equivalent_status_(status); + goto err; + } + if(!write_metadata_block_data_(tempfile, &status, node->data)) { + chain->status = get_equivalent_status_(status); + goto err; + } + } + /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/ + + /* copy the file postfix (everything after the metadata) */ + if(0 != fseeko(f, chain->last_offset, SEEK_SET)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + goto err; + } + if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) { + chain->status = get_equivalent_status_(status); + goto err; + } + + /* move the tempfile on top of the original */ + (void)fclose(f); + if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status)) + return false; + + return true; + +err: + (void)fclose(f); + cleanup_tempfile_(&tempfile, &tempfilename); + return false; +} + +/* assumes 'handle' is already at beginning of file */ +static FLAC__bool chain_rewrite_file_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb) +{ + FLAC__Metadata_SimpleIteratorStatus status; + const FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 == chain->filename); + FLAC__ASSERT(0 != chain->head); + + /* copy the file prefix (data up to first metadata block */ + if(!copy_n_bytes_from_file_cb_(handle, read_cb, temp_handle, temp_write_cb, chain->first_offset, &status)) { + chain->status = get_equivalent_status_(status); + return false; + } + + /* write the metadata */ + for(node = chain->head; node; node = node->next) { + if(!write_metadata_block_header_cb_(temp_handle, temp_write_cb, node->data)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; + return false; + } + if(!write_metadata_block_data_cb_(temp_handle, temp_write_cb, node->data)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; + return false; + } + } + /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/ + + /* copy the file postfix (everything after the metadata) */ + if(0 != seek_cb(handle, chain->last_offset, SEEK_SET)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + return false; + } + if(!copy_remaining_bytes_from_file_cb_(handle, read_cb, eof_cb, temp_handle, temp_write_cb, &status)) { + chain->status = get_equivalent_status_(status); + return false; + } + + return true; +} + +FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void) +{ + FLAC__Metadata_Chain *chain = calloc(1, sizeof(FLAC__Metadata_Chain)); + + if(0 != chain) + chain_init_(chain); + + return chain; +} + +FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain) +{ + FLAC__ASSERT(0 != chain); + + chain_clear_(chain); + + free(chain); +} + +FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain) +{ + FLAC__Metadata_ChainStatus status; + + FLAC__ASSERT(0 != chain); + + status = chain->status; + chain->status = FLAC__METADATA_CHAIN_STATUS_OK; + return status; +} + +static FLAC__bool chain_read_(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool is_ogg) +{ + FILE *file; + FLAC__bool ret; + + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 != filename); + + chain_clear_(chain); + + if(0 == (chain->filename = strdup(filename))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + + chain->is_ogg = is_ogg; + + if(0 == (file = flac_fopen(filename, "rb"))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + return false; + } + + /* the function also sets chain->status for us */ + ret = is_ogg? + chain_read_ogg_cb_(chain, file, (FLAC__IOCallback_Read)fread) : + chain_read_cb_(chain, file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, ftell_wrapper_) + ; + + fclose(file); + + return ret; +} + +FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename) +{ + return chain_read_(chain, filename, /*is_ogg=*/false); +} + +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename) +{ + return chain_read_(chain, filename, /*is_ogg=*/true); +} + +static FLAC__bool chain_read_with_callbacks_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__bool is_ogg) +{ + FLAC__bool ret; + + FLAC__ASSERT(0 != chain); + + chain_clear_(chain); + + if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.tell) { + chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; + return false; + } + + chain->is_ogg = is_ogg; + + /* rewind */ + if(0 != callbacks.seek(handle, 0, SEEK_SET)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + return false; + } + + /* the function also sets chain->status for us */ + ret = is_ogg? + chain_read_ogg_cb_(chain, handle, callbacks.read) : + chain_read_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.tell) + ; + + return ret; +} + +FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) +{ + return chain_read_with_callbacks_(chain, handle, callbacks, /*is_ogg=*/false); +} + +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) +{ + return chain_read_with_callbacks_(chain, handle, callbacks, /*is_ogg=*/true); +} + +typedef enum { + LBS_NONE = 0, + LBS_SIZE_CHANGED, + LBS_BLOCK_ADDED, + LBS_BLOCK_REMOVED +} LastBlockState; + +FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding) +{ + /* This does all the same checks that are in chain_prepare_for_write_() + * but doesn't actually alter the chain. Make sure to update the logic + * here if chain_prepare_for_write_() changes. + */ + FLAC__off_t current_length; + LastBlockState lbs_state = LBS_NONE; + unsigned lbs_size = 0; + + FLAC__ASSERT(0 != chain); + + current_length = chain_calculate_length_(chain); + + if(use_padding) { + const FLAC__Metadata_Node * const node = chain->tail; + /* if the metadata shrank and the last block is padding, we just extend the last padding block */ + if(current_length < chain->initial_length && node->data->type == FLAC__METADATA_TYPE_PADDING) { + lbs_state = LBS_SIZE_CHANGED; + lbs_size = node->data->length + (chain->initial_length - current_length); + } + /* if the metadata shrank more than 4 bytes then there's room to add another padding block */ + else if(current_length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) { + lbs_state = LBS_BLOCK_ADDED; + lbs_size = chain->initial_length - (current_length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + } + /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */ + else if(current_length > chain->initial_length) { + const FLAC__off_t delta = current_length - chain->initial_length; + if(node->data->type == FLAC__METADATA_TYPE_PADDING) { + /* if the delta is exactly the size of the last padding block, remove the padding block */ + if((FLAC__off_t)node->data->length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) { + lbs_state = LBS_BLOCK_REMOVED; + lbs_size = 0; + } + /* if there is at least 'delta' bytes of padding, trim the padding down */ + else if((FLAC__off_t)node->data->length >= delta) { + lbs_state = LBS_SIZE_CHANGED; + lbs_size = node->data->length - delta; + } + } + } + } + + current_length = 0; + /* check sizes of all metadata blocks; reduce padding size if necessary */ + { + const FLAC__Metadata_Node *node; + for(node = chain->head; node; node = node->next) { + unsigned block_len = node->data->length; + if(node == chain->tail) { + if(lbs_state == LBS_BLOCK_REMOVED) + continue; + else if(lbs_state == LBS_SIZE_CHANGED) + block_len = lbs_size; + } + if(block_len >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) { + if(node->data->type == FLAC__METADATA_TYPE_PADDING) + block_len = (1u << FLAC__STREAM_METADATA_LENGTH_LEN) - 1; + else + return false /* the return value doesn't matter */; + } + current_length += (FLAC__STREAM_METADATA_HEADER_LENGTH + block_len); + } + + if(lbs_state == LBS_BLOCK_ADDED) { + /* test added padding block */ + unsigned block_len = lbs_size; + if(block_len >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + block_len = (1u << FLAC__STREAM_METADATA_LENGTH_LEN) - 1; + current_length += (FLAC__STREAM_METADATA_HEADER_LENGTH + block_len); + } + } + + return (current_length != chain->initial_length); +} + +FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats) +{ + struct flac_stat_s stats; + const char *tempfile_path_prefix = 0; + FLAC__off_t current_length; + + FLAC__ASSERT(0 != chain); + + if (chain->is_ogg) { /* cannot write back to Ogg FLAC yet */ + chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; + return false; + } + + if (0 == chain->filename) { + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH; + return false; + } + + current_length = chain_prepare_for_write_(chain, use_padding); + + /* a return value of 0 means there was an error; chain->status is already set */ + if (0 == current_length) + return false; + + if(preserve_file_stats) + get_file_stats_(chain->filename, &stats); + + if(current_length == chain->initial_length) { + if(!chain_rewrite_metadata_in_place_(chain)) + return false; + } + else { + if(!chain_rewrite_file_(chain, tempfile_path_prefix)) + return false; + + /* recompute lengths and offsets */ + { + const FLAC__Metadata_Node *node; + chain->initial_length = current_length; + chain->last_offset = chain->first_offset; + for(node = chain->head; node; node = node->next) + chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); + } + } + + if(preserve_file_stats) + set_file_stats_(chain->filename, &stats); + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) +{ + FLAC__off_t current_length; + + FLAC__ASSERT(0 != chain); + + if (chain->is_ogg) { /* cannot write back to Ogg FLAC yet */ + chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; + return false; + } + + if (0 != chain->filename) { + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH; + return false; + } + + if (0 == callbacks.write || 0 == callbacks.seek) { + chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; + return false; + } + + if (FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL; + return false; + } + + current_length = chain_prepare_for_write_(chain, use_padding); + + /* a return value of 0 means there was an error; chain->status is already set */ + if (0 == current_length) + return false; + + FLAC__ASSERT(current_length == chain->initial_length); + + return chain_rewrite_metadata_in_place_cb_(chain, handle, callbacks.write, callbacks.seek); +} + +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks) +{ + FLAC__off_t current_length; + + FLAC__ASSERT(0 != chain); + + if (chain->is_ogg) { /* cannot write back to Ogg FLAC yet */ + chain->status = FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; + return false; + } + + if (0 != chain->filename) { + chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH; + return false; + } + + if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.eof) { + chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; + return false; + } + if (0 == temp_callbacks.write) { + chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; + return false; + } + + if (!FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL; + return false; + } + + current_length = chain_prepare_for_write_(chain, use_padding); + + /* a return value of 0 means there was an error; chain->status is already set */ + if (0 == current_length) + return false; + + FLAC__ASSERT(current_length != chain->initial_length); + + /* rewind */ + if(0 != callbacks.seek(handle, 0, SEEK_SET)) { + chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + return false; + } + + if(!chain_rewrite_file_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.eof, temp_handle, temp_callbacks.write)) + return false; + + /* recompute lengths and offsets */ + { + const FLAC__Metadata_Node *node; + chain->initial_length = current_length; + chain->last_offset = chain->first_offset; + for(node = chain->head; node; node = node->next) + chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); + } + + return true; +} + +FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain) +{ + FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != chain); + + for(node = chain->head; node; ) { + if(!chain_merge_adjacent_padding_(chain, node)) + node = node->next; + } +} + +FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain) +{ + FLAC__Metadata_Node *node, *save; + unsigned i; + + FLAC__ASSERT(0 != chain); + + /* + * Don't try and be too smart... this simple algo is good enough for + * the small number of nodes that we deal with. + */ + for(i = 0, node = chain->head; i < chain->nodes; i++) { + if(node->data->type == FLAC__METADATA_TYPE_PADDING) { + save = node->next; + chain_remove_node_(chain, node); + chain_append_node_(chain, node); + node = save; + } + else { + node = node->next; + } + } + + FLAC__metadata_chain_merge_padding(chain); +} + + +FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void) +{ + FLAC__Metadata_Iterator *iterator = calloc(1, sizeof(FLAC__Metadata_Iterator)); + + /* calloc() implies: + iterator->current = 0; + iterator->chain = 0; + */ + + return iterator; +} + +FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + + free(iterator); +} + +FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != chain); + FLAC__ASSERT(0 != chain->head); + + iterator->chain = chain; + iterator->current = chain->head; +} + +FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + + if(0 == iterator->current || 0 == iterator->current->next) + return false; + + iterator->current = iterator->current->next; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + + if(0 == iterator->current || 0 == iterator->current->prev) + return false; + + iterator->current = iterator->current->prev; + return true; +} + +FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + FLAC__ASSERT(0 != iterator->current->data); + + return iterator->current->data->type; +} + +FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + + return iterator->current->data; +} + +FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != block); + return FLAC__metadata_iterator_delete_block(iterator, false) && FLAC__metadata_iterator_insert_block_after(iterator, block); +} + +FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding) +{ + FLAC__Metadata_Node *save; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + + if(0 == iterator->current->prev) { + FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO); + return false; + } + + save = iterator->current->prev; + + if(replace_with_padding) { + FLAC__metadata_object_delete_data(iterator->current->data); + iterator->current->data->type = FLAC__METADATA_TYPE_PADDING; + } + else { + chain_delete_node_(iterator->chain, iterator->current); + } + + iterator->current = save; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block) +{ + FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + FLAC__ASSERT(0 != block); + + if(block->type == FLAC__METADATA_TYPE_STREAMINFO) + return false; + + if(0 == iterator->current->prev) { + FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO); + return false; + } + + if(0 == (node = node_new_())) + return false; + + node->data = block; + iterator_insert_node_(iterator, node); + iterator->current = node; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block) +{ + FLAC__Metadata_Node *node; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->current); + FLAC__ASSERT(0 != block); + + if(block->type == FLAC__METADATA_TYPE_STREAMINFO) + return false; + + if(0 == (node = node_new_())) + return false; + + node->data = block; + iterator_insert_node_after_(iterator, node); + iterator->current = node; + return true; +} + + +/**************************************************************************** + * + * Local function definitions + * + ***************************************************************************/ + +void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes) +{ + unsigned i; + + b += bytes; + + for(i = 0; i < bytes; i++) { + *(--b) = (FLAC__byte)(val & 0xff); + val >>= 8; + } +} + +void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes) +{ + unsigned i; + + for(i = 0; i < bytes; i++) { + *(b++) = (FLAC__byte)(val & 0xff); + val >>= 8; + } +} + +void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes) +{ + unsigned i; + + b += bytes; + + for(i = 0; i < bytes; i++) { + *(--b) = (FLAC__byte)(val & 0xff); + val >>= 8; + } +} + +FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes) +{ + FLAC__uint32 ret = 0; + unsigned i; + + for(i = 0; i < bytes; i++) + ret = (ret << 8) | (FLAC__uint32)(*b++); + + return ret; +} + +FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes) +{ + FLAC__uint32 ret = 0; + unsigned i; + + b += bytes; + + for(i = 0; i < bytes; i++) + ret = (ret << 8) | (FLAC__uint32)(*--b); + + return ret; +} + +FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes) +{ + FLAC__uint64 ret = 0; + unsigned i; + + for(i = 0; i < bytes; i++) + ret = (ret << 8) | (FLAC__uint64)(*b++); + + return ret; +} + +FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, &iterator->is_last, &iterator->type, &iterator->length)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + + return true; +} + +FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, block); + + return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK); +} + +FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length) +{ + FLAC__byte raw_header[FLAC__STREAM_METADATA_HEADER_LENGTH]; + + if(read_cb(raw_header, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH) + return false; + + *is_last = raw_header[0] & 0x80? true : false; + *type = (FLAC__MetadataType)(raw_header[0] & 0x7f); + *length = unpack_uint32_(raw_header + 1, 3); + + /* Note that we don't check: + * if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED) + * we just will read in an opaque block + */ + + return true; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block) +{ + switch(block->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + return read_metadata_block_data_streaminfo_cb_(handle, read_cb, &block->data.stream_info); + case FLAC__METADATA_TYPE_PADDING: + return read_metadata_block_data_padding_cb_(handle, seek_cb, &block->data.padding, block->length); + case FLAC__METADATA_TYPE_APPLICATION: + return read_metadata_block_data_application_cb_(handle, read_cb, &block->data.application, block->length); + case FLAC__METADATA_TYPE_SEEKTABLE: + return read_metadata_block_data_seektable_cb_(handle, read_cb, &block->data.seek_table, block->length); + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + return read_metadata_block_data_vorbis_comment_cb_(handle, read_cb, seek_cb, &block->data.vorbis_comment, block->length); + case FLAC__METADATA_TYPE_CUESHEET: + return read_metadata_block_data_cuesheet_cb_(handle, read_cb, &block->data.cue_sheet); + case FLAC__METADATA_TYPE_PICTURE: + return read_metadata_block_data_picture_cb_(handle, read_cb, &block->data.picture); + default: + return read_metadata_block_data_unknown_cb_(handle, read_cb, &block->data.unknown, block->length); + } +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block) +{ + FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH], *b; + + if(read_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + + b = buffer; + + /* we are using hardcoded numbers for simplicity but we should + * probably eventually write a bit-level unpacker and use the + * _STREAMINFO_ constants. + */ + block->min_blocksize = unpack_uint32_(b, 2); b += 2; + block->max_blocksize = unpack_uint32_(b, 2); b += 2; + block->min_framesize = unpack_uint32_(b, 3); b += 3; + block->max_framesize = unpack_uint32_(b, 3); b += 3; + block->sample_rate = (unpack_uint32_(b, 2) << 4) | ((unsigned)(b[2] & 0xf0) >> 4); + block->channels = (unsigned)((b[2] & 0x0e) >> 1) + 1; + block->bits_per_sample = ((((unsigned)(b[2] & 0x01)) << 4) | (((unsigned)(b[3] & 0xf0)) >> 4)) + 1; + block->total_samples = (((FLAC__uint64)(b[3] & 0x0f)) << 32) | unpack_uint64_(b+4, 4); + memcpy(block->md5sum, b+8, 16); + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length) +{ + (void)block; /* nothing to do; we don't care about reading the padding bytes */ + + if(0 != seek_cb(handle, block_length, SEEK_CUR)) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length) +{ + const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + + if(read_cb(block->id, 1, id_bytes, handle) != id_bytes) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + + if(block_length < id_bytes) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + + block_length -= id_bytes; + + if(block_length == 0) { + block->data = 0; + } + else { + if(0 == (block->data = malloc(block_length))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + if(read_cb(block->data, 1, block_length, handle) != block_length) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length) +{ + unsigned i; + FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH]; + + FLAC__ASSERT(block_length % FLAC__STREAM_METADATA_SEEKPOINT_LENGTH == 0); + + block->num_points = block_length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + + if(block->num_points == 0) + block->points = 0; + else if(0 == (block->points = safe_malloc_mul_2op_p(block->num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + for(i = 0; i < block->num_points; i++) { + if(read_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + /* some MAGIC NUMBERs here */ + block->points[i].sample_number = unpack_uint64_(buffer, 8); + block->points[i].stream_offset = unpack_uint64_(buffer+8, 8); + block->points[i].frame_samples = unpack_uint32_(buffer+16, 2); + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry, unsigned max_length) +{ + const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8; + FLAC__byte buffer[4]; /* magic number is asserted below */ + + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8 == sizeof(buffer)); + + if(max_length < entry_length_len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA; + + max_length -= entry_length_len; + if(read_cb(buffer, 1, entry_length_len, handle) != entry_length_len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + entry->length = unpack_uint32_little_endian_(buffer, entry_length_len); + if(max_length < entry->length) { + entry->length = 0; + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA; + } else max_length -= entry->length; + + if(0 != entry->entry) + free(entry->entry); + + if(entry->length == 0) { + entry->entry = 0; + } + else { + if(0 == (entry->entry = safe_malloc_add_2op_(entry->length, /*+*/1))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + if(read_cb(entry->entry, 1, entry->length, handle) != entry->length) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + + entry->entry[entry->length] = '\0'; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_VorbisComment *block, unsigned block_length) +{ + unsigned i; + FLAC__Metadata_SimpleIteratorStatus status; + const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8; + FLAC__byte buffer[4]; /* magic number is asserted below */ + + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8 == sizeof(buffer)); + + status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, &(block->vendor_string), block_length); + if(block_length >= 4) + block_length -= 4; + if(status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA) + goto skip; + else if(status != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK) + return status; + block_length -= block->vendor_string.length; + + if(block_length < num_comments_len) goto skip; else block_length -= num_comments_len; + if(read_cb(buffer, 1, num_comments_len, handle) != num_comments_len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->num_comments = unpack_uint32_little_endian_(buffer, num_comments_len); + + if(block->num_comments == 0) { + block->comments = 0; + } + else if(0 == (block->comments = calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { + block->num_comments = 0; + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + } + + for(i = 0; i < block->num_comments; i++) { + status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, block->comments + i, block_length); + if(block_length >= 4) block_length -= 4; + if(status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA) { + block->num_comments = i; + goto skip; + } + else if(status != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK) return status; + block_length -= block->comments[i].length; + } + + skip: + if(block_length > 0) { + /* bad metadata */ + if(0 != seek_cb(handle, block_length, SEEK_CUR)) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track) +{ + unsigned i, len; + FLAC__byte buffer[32]; /* asserted below that this is big enough */ + + FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64)); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + track->offset = unpack_uint64_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + track->number = (FLAC__byte)unpack_uint32_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8; + if(read_cb(track->isrc, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + + FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0); + len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN == 1); + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN == 1); + track->type = buffer[0] >> 7; + track->pre_emphasis = (buffer[0] >> 6) & 1; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + track->num_indices = (FLAC__byte)unpack_uint32_(buffer, len); + + if(track->num_indices == 0) { + track->indices = 0; + } + else if(0 == (track->indices = calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + for(i = 0; i < track->num_indices; i++) { + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + track->indices[i].offset = unpack_uint64_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + track->indices[i].number = (FLAC__byte)unpack_uint32_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block) +{ + unsigned i, len; + FLAC__Metadata_SimpleIteratorStatus status; + FLAC__byte buffer[1024]; /* MSVC needs a constant expression so we put a magic number and assert */ + + FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)/8 <= sizeof(buffer)); + FLAC__ASSERT(sizeof(FLAC__uint64) <= sizeof(buffer)); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8; + if(read_cb(block->media_catalog_number, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->lead_in = unpack_uint64_(buffer, len); + + FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0); + len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->is_cd = buffer[0]&0x80? true : false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->num_tracks = unpack_uint32_(buffer, len); + + if(block->num_tracks == 0) { + block->tracks = 0; + } + else if(0 == (block->tracks = calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + for(i = 0; i < block->num_tracks; i++) { + if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_cuesheet_track_cb_(handle, read_cb, block->tracks + i))) + return status; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstring_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__byte **data, FLAC__uint32 *length, FLAC__uint32 length_len) +{ + FLAC__byte buffer[sizeof(FLAC__uint32)]; + + FLAC__ASSERT(0 != data); + FLAC__ASSERT(length_len%8 == 0); + + length_len /= 8; /* convert to bytes */ + + FLAC__ASSERT(sizeof(buffer) >= length_len); + + if(read_cb(buffer, 1, length_len, handle) != length_len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + *length = unpack_uint32_(buffer, length_len); + + if(0 != *data) + free(*data); + + if(0 == (*data = safe_malloc_add_2op_(*length, /*+*/1))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + if(*length > 0) { + if(read_cb(*data, 1, *length, handle) != *length) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + } + + (*data)[*length] = '\0'; + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Picture *block) +{ + FLAC__Metadata_SimpleIteratorStatus status; + FLAC__byte buffer[4]; /* asserted below that this is big enough */ + FLAC__uint32 len; + + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_TYPE_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_COLORS_LEN/8); + + FLAC__ASSERT(FLAC__STREAM_METADATA_PICTURE_TYPE_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_PICTURE_TYPE_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->type = (FLAC__StreamMetadata_Picture_Type)unpack_uint32_(buffer, len); + + if((status = read_metadata_block_data_picture_cstring_cb_(handle, read_cb, (FLAC__byte**)(&(block->mime_type)), &len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK) + return status; + + if((status = read_metadata_block_data_picture_cstring_cb_(handle, read_cb, &(block->description), &len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK) + return status; + + FLAC__ASSERT(FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->width = unpack_uint32_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->height = unpack_uint32_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->depth = unpack_uint32_(buffer, len); + + FLAC__ASSERT(FLAC__STREAM_METADATA_PICTURE_COLORS_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_PICTURE_COLORS_LEN / 8; + if(read_cb(buffer, 1, len, handle) != len) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block->colors = unpack_uint32_(buffer, len); + + /* for convenience we use read_metadata_block_data_picture_cstring_cb_() even though it adds an extra terminating NUL we don't use */ + if((status = read_metadata_block_data_picture_cstring_cb_(handle, read_cb, &(block->data), &(block->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK) + return status; + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length) +{ + if(block_length == 0) { + block->data = 0; + } + else { + if(0 == (block->data = malloc(block_length))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + if(read_cb(block->data, 1, block_length, handle) != block_length) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + +FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != file); + FLAC__ASSERT(0 != status); + + if(!write_metadata_block_header_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + + return true; +} + +FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != file); + FLAC__ASSERT(0 != status); + + if (write_metadata_block_data_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; + return true; + } + else { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } +} + +FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block) +{ + FLAC__byte buffer[FLAC__STREAM_METADATA_HEADER_LENGTH]; + + FLAC__ASSERT(block->length < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); + /* double protection */ + if(block->length >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + return false; + + buffer[0] = (block->is_last? 0x80 : 0) | (FLAC__byte)block->type; + pack_uint32_(block->length, buffer + 1, 3); + + if(write_cb(buffer, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH) + return false; + + return true; +} + +FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != block); + + switch(block->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + return write_metadata_block_data_streaminfo_cb_(handle, write_cb, &block->data.stream_info); + case FLAC__METADATA_TYPE_PADDING: + return write_metadata_block_data_padding_cb_(handle, write_cb, &block->data.padding, block->length); + case FLAC__METADATA_TYPE_APPLICATION: + return write_metadata_block_data_application_cb_(handle, write_cb, &block->data.application, block->length); + case FLAC__METADATA_TYPE_SEEKTABLE: + return write_metadata_block_data_seektable_cb_(handle, write_cb, &block->data.seek_table); + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + return write_metadata_block_data_vorbis_comment_cb_(handle, write_cb, &block->data.vorbis_comment); + case FLAC__METADATA_TYPE_CUESHEET: + return write_metadata_block_data_cuesheet_cb_(handle, write_cb, &block->data.cue_sheet); + case FLAC__METADATA_TYPE_PICTURE: + return write_metadata_block_data_picture_cb_(handle, write_cb, &block->data.picture); + default: + return write_metadata_block_data_unknown_cb_(handle, write_cb, &block->data.unknown, block->length); + } +} + +FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block) +{ + FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH]; + const unsigned channels1 = block->channels - 1; + const unsigned bps1 = block->bits_per_sample - 1; + + /* we are using hardcoded numbers for simplicity but we should + * probably eventually write a bit-level packer and use the + * _STREAMINFO_ constants. + */ + pack_uint32_(block->min_blocksize, buffer, 2); + pack_uint32_(block->max_blocksize, buffer+2, 2); + pack_uint32_(block->min_framesize, buffer+4, 3); + pack_uint32_(block->max_framesize, buffer+7, 3); + buffer[10] = (block->sample_rate >> 12) & 0xff; + buffer[11] = (block->sample_rate >> 4) & 0xff; + buffer[12] = ((block->sample_rate & 0x0f) << 4) | (channels1 << 1) | (bps1 >> 4); + buffer[13] = (FLAC__byte)(((bps1 & 0x0f) << 4) | ((block->total_samples >> 32) & 0x0f)); + pack_uint32_((FLAC__uint32)block->total_samples, buffer+14, 4); + memcpy(buffer+18, block->md5sum, 16); + + if(write_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) + return false; + + return true; +} + +FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length) +{ + unsigned i, n = block_length; + FLAC__byte buffer[1024]; + + (void)block; + + memset(buffer, 0, 1024); + + for(i = 0; i < n/1024; i++) + if(write_cb(buffer, 1, 1024, handle) != 1024) + return false; + + n %= 1024; + + if(write_cb(buffer, 1, n, handle) != n) + return false; + + return true; +} + +FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length) +{ + const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + + if(write_cb(block->id, 1, id_bytes, handle) != id_bytes) + return false; + + block_length -= id_bytes; + + if(write_cb(block->data, 1, block_length, handle) != block_length) + return false; + + return true; +} + +FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block) +{ + unsigned i; + FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH]; + + for(i = 0; i < block->num_points; i++) { + /* some MAGIC NUMBERs here */ + pack_uint64_(block->points[i].sample_number, buffer, 8); + pack_uint64_(block->points[i].stream_offset, buffer+8, 8); + pack_uint32_(block->points[i].frame_samples, buffer+16, 2); + if(write_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH) + return false; + } + + return true; +} + +FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block) +{ + unsigned i; + const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8; + const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8; + FLAC__byte buffer[4]; /* magic number is asserted below */ + + FLAC__ASSERT(flac_max(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN, FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8 == sizeof(buffer)); + + pack_uint32_little_endian_(block->vendor_string.length, buffer, entry_length_len); + if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len) + return false; + if(write_cb(block->vendor_string.entry, 1, block->vendor_string.length, handle) != block->vendor_string.length) + return false; + + pack_uint32_little_endian_(block->num_comments, buffer, num_comments_len); + if(write_cb(buffer, 1, num_comments_len, handle) != num_comments_len) + return false; + + for(i = 0; i < block->num_comments; i++) { + pack_uint32_little_endian_(block->comments[i].length, buffer, entry_length_len); + if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len) + return false; + if(write_cb(block->comments[i].entry, 1, block->comments[i].length, handle) != block->comments[i].length) + return false; + } + + return true; +} + +FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block) +{ + unsigned i, j, len; + FLAC__byte buffer[1024]; /* asserted below that this is big enough */ + + FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64)); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8; + if(write_cb(block->media_catalog_number, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8; + pack_uint64_(block->lead_in, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0); + len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8; + memset(buffer, 0, len); + if(block->is_cd) + buffer[0] |= 0x80; + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8; + pack_uint32_(block->num_tracks, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + for(i = 0; i < block->num_tracks; i++) { + FLAC__StreamMetadata_CueSheet_Track *track = block->tracks + i; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8; + pack_uint64_(track->offset, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8; + pack_uint32_(track->number, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8; + if(write_cb(track->isrc, 1, len, handle) != len) + return false; + + FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0); + len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8; + memset(buffer, 0, len); + buffer[0] = (track->type << 7) | (track->pre_emphasis << 6); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8; + pack_uint32_(track->num_indices, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + for(j = 0; j < track->num_indices; j++) { + FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + j; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8; + pack_uint64_(indx->offset, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8; + pack_uint32_(indx->number, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0); + len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8; + memset(buffer, 0, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + } + } + + return true; +} + +FLAC__bool write_metadata_block_data_picture_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Picture *block) +{ + unsigned len; + size_t slen; + FLAC__byte buffer[4]; /* magic number is asserted below */ + + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_TYPE_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_COLORS_LEN%8); + FLAC__ASSERT(0 == FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN%8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_TYPE_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_COLORS_LEN/8); + FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN/8); + + len = FLAC__STREAM_METADATA_PICTURE_TYPE_LEN/8; + pack_uint32_(block->type, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN/8; + slen = strlen(block->mime_type); + pack_uint32_(slen, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + if(write_cb(block->mime_type, 1, slen, handle) != slen) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN/8; + slen = strlen((const char *)block->description); + pack_uint32_(slen, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + if(write_cb(block->description, 1, slen, handle) != slen) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN/8; + pack_uint32_(block->width, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN/8; + pack_uint32_(block->height, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN/8; + pack_uint32_(block->depth, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_COLORS_LEN/8; + pack_uint32_(block->colors, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + + len = FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN/8; + pack_uint32_(block->data_length, buffer, len); + if(write_cb(buffer, 1, len, handle) != len) + return false; + if(write_cb(block->data, 1, block->data_length, handle) != block->data_length) + return false; + + return true; +} + +FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length) +{ + if(write_cb(block->data, 1, block_length, handle) != block_length) + return false; + + return true; +} + +FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block) +{ + if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + if(!write_metadata_block_header_(iterator->file, &iterator->status, block)) + return false; + + if(!write_metadata_block_data_(iterator->file, &iterator->status, block)) + return false; + + if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + return read_metadata_block_header_(iterator); +} + +FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last) +{ + FLAC__StreamMetadata *padding; + + if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + block->is_last = false; + + if(!write_metadata_block_header_(iterator->file, &iterator->status, block)) + return false; + + if(!write_metadata_block_data_(iterator->file, &iterator->status, block)) + return false; + + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + padding->is_last = padding_is_last; + padding->length = padding_length; + + if(!write_metadata_block_header_(iterator->file, &iterator->status, padding)) { + FLAC__metadata_object_delete(padding); + return false; + } + + if(!write_metadata_block_data_(iterator->file, &iterator->status, padding)) { + FLAC__metadata_object_delete(padding); + return false; + } + + FLAC__metadata_object_delete(padding); + + if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + return read_metadata_block_header_(iterator); +} + +FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append) +{ + FILE *tempfile = NULL; + char *tempfilename = NULL; + int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */ + FLAC__off_t fixup_is_last_flag_offset = -1; + + FLAC__ASSERT(0 != block || append == false); + + if(iterator->is_last) { + if(append) { + fixup_is_last_code = 1; /* 1 => clear the is_last flag at the following offset */ + fixup_is_last_flag_offset = iterator->offset[iterator->depth]; + } + else if(0 == block) { + simple_iterator_push_(iterator); + if(!FLAC__metadata_simple_iterator_prev(iterator)) { + (void)simple_iterator_pop_(iterator); + return false; + } + fixup_is_last_code = -1; /* -1 => set the is_last the flag at the following offset */ + fixup_is_last_flag_offset = iterator->offset[iterator->depth]; + if(!simple_iterator_pop_(iterator)) + return false; + } + } + + if(!simple_iterator_copy_file_prefix_(iterator, &tempfile, &tempfilename, append)) + return false; + + if(0 != block) { + if(!write_metadata_block_header_(tempfile, &iterator->status, block)) { + cleanup_tempfile_(&tempfile, &tempfilename); + return false; + } + + if(!write_metadata_block_data_(tempfile, &iterator->status, block)) { + cleanup_tempfile_(&tempfile, &tempfilename); + return false; + } + } + + if(!simple_iterator_copy_file_postfix_(iterator, &tempfile, &tempfilename, fixup_is_last_code, fixup_is_last_flag_offset, block==0)) + return false; + + if(append) + return FLAC__metadata_simple_iterator_next(iterator); + + return true; +} + +void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(iterator->depth+1 < SIMPLE_ITERATOR_MAX_PUSH_DEPTH); + iterator->offset[iterator->depth+1] = iterator->offset[iterator->depth]; + iterator->depth++; +} + +FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(iterator->depth > 0); + iterator->depth--; + if(0 != fseeko(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + return read_metadata_block_header_(iterator); +} + +/* return meanings: + * 0: ok + * 1: read error + * 2: seek error + * 3: not a FLAC file + */ +unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb) +{ + FLAC__byte buffer[4]; + size_t n; + unsigned i; + + FLAC__ASSERT(FLAC__STREAM_SYNC_LENGTH == sizeof(buffer)); + + /* skip any id3v2 tag */ + errno = 0; + n = read_cb(buffer, 1, 4, handle); + if(errno) + return 1; + else if(n != 4) + return 3; + else if(0 == memcmp(buffer, "ID3", 3)) { + unsigned tag_length = 0; + + /* skip to the tag length */ + if(seek_cb(handle, 2, SEEK_CUR) < 0) + return 2; + + /* read the length */ + for(i = 0; i < 4; i++) { + if(read_cb(buffer, 1, 1, handle) < 1 || buffer[0] & 0x80) + return 1; + tag_length <<= 7; + tag_length |= (buffer[0] & 0x7f); + } + + /* skip the rest of the tag */ + if(seek_cb(handle, tag_length, SEEK_CUR) < 0) + return 2; + + /* read the stream sync code */ + errno = 0; + n = read_cb(buffer, 1, 4, handle); + if(errno) + return 1; + else if(n != 4) + return 3; + } + + /* check for the fLaC signature */ + if(0 == memcmp(FLAC__STREAM_SYNC_STRING, buffer, FLAC__STREAM_SYNC_LENGTH)) + return 0; + else + return 3; +} + +unsigned seek_to_first_metadata_block_(FILE *f) +{ + return seek_to_first_metadata_block_cb_((FLAC__IOHandle)f, (FLAC__IOCallback_Read)fread, fseek_wrapper_); +} + +FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append) +{ + const FLAC__off_t offset_end = append? iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length : iterator->offset[iterator->depth]; + + if(0 != fseeko(iterator->file, 0, SEEK_SET)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + if(!open_tempfile_(iterator->filename, iterator->tempfile_path_prefix, tempfile, tempfilename, &iterator->status)) { + cleanup_tempfile_(tempfile, tempfilename); + return false; + } + if(!copy_n_bytes_from_file_(iterator->file, *tempfile, offset_end, &iterator->status)) { + cleanup_tempfile_(tempfile, tempfilename); + return false; + } + + return true; +} + +FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, FLAC__off_t fixup_is_last_flag_offset, FLAC__bool backup) +{ + FLAC__off_t save_offset = iterator->offset[iterator->depth]; + FLAC__ASSERT(0 != *tempfile); + + if(0 != fseeko(iterator->file, save_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length, SEEK_SET)) { + cleanup_tempfile_(tempfile, tempfilename); + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + if(!copy_remaining_bytes_from_file_(iterator->file, *tempfile, &iterator->status)) { + cleanup_tempfile_(tempfile, tempfilename); + return false; + } + + if(fixup_is_last_code != 0) { + /* + * if code == 1, it means a block was appended to the end so + * we have to clear the is_last flag of the previous block + * if code == -1, it means the last block was deleted so + * we have to set the is_last flag of the previous block + */ + /* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */ + FLAC__byte x; + if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) { + cleanup_tempfile_(tempfile, tempfilename); + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + if(fread(&x, 1, 1, *tempfile) != 1) { + cleanup_tempfile_(tempfile, tempfilename); + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + if(fixup_is_last_code > 0) { + FLAC__ASSERT(x & 0x80); + x &= 0x7f; + } + else { + FLAC__ASSERT(!(x & 0x80)); + x |= 0x80; + } + if(0 != fseeko(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) { + cleanup_tempfile_(tempfile, tempfilename); + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + if(local__fwrite(&x, 1, 1, *tempfile) != 1) { + cleanup_tempfile_(tempfile, tempfilename); + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + } + + (void)fclose(iterator->file); + + if(!transport_tempfile_(iterator->filename, tempfile, tempfilename, &iterator->status)) + return false; + + if(iterator->has_stats) + set_file_stats_(iterator->filename, &iterator->stats); + + if(!simple_iterator_prime_input_(iterator, !iterator->is_writable)) + return false; + if(backup) { + while(iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length < save_offset) + if(!FLAC__metadata_simple_iterator_next(iterator)) + return false; + return true; + } + else { + /* move the iterator to it's original block faster by faking a push, then doing a pop_ */ + FLAC__ASSERT(iterator->depth == 0); + iterator->offset[0] = save_offset; + iterator->depth++; + return simple_iterator_pop_(iterator); + } +} + +FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) +{ + FLAC__byte buffer[8192]; + size_t n; + + FLAC__ASSERT(bytes >= 0); + while(bytes > 0) { + n = flac_min(sizeof(buffer), (size_t)bytes); + if(fread(buffer, 1, n, file) != n) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + if(local__fwrite(buffer, 1, n, tempfile) != n) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + bytes -= n; + } + + return true; +} + +FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) +{ + FLAC__byte buffer[8192]; + size_t n; + + FLAC__ASSERT(bytes >= 0); + while(bytes > 0) { + n = flac_min(sizeof(buffer), (size_t)bytes); + if(read_cb(buffer, 1, n, handle) != n) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + if(temp_write_cb(buffer, 1, n, temp_handle) != n) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + bytes -= n; + } + + return true; +} + +FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status) +{ + FLAC__byte buffer[8192]; + size_t n; + + while(!feof(file)) { + n = fread(buffer, 1, sizeof(buffer), file); + if(n == 0 && !feof(file)) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + if(n > 0 && local__fwrite(buffer, 1, n, tempfile) != n) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + } + + return true; +} + +FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status) +{ + FLAC__byte buffer[8192]; + size_t n; + + while(!eof_cb(handle)) { + n = read_cb(buffer, 1, sizeof(buffer), handle); + if(n == 0 && !eof_cb(handle)) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + if(n > 0 && temp_write_cb(buffer, 1, n, temp_handle) != n) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + } + + return true; +} + +static int +local_snprintf(char *str, size_t size, const char *fmt, ...) +{ + va_list va; + int rc; + +#if defined _MSC_VER + if (size == 0) + return 1024; +#endif + + va_start (va, fmt); + +#if defined _MSC_VER + rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va); + if (rc < 0) + rc = size - 1; +#elif defined __MINGW32__ + rc = __mingw_vsnprintf (str, size, fmt, va); +#else + rc = vsnprintf (str, size, fmt, va); +#endif + va_end (va); + + return rc; +} + +FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status) +{ + static const char *tempfile_suffix = ".metadata_edit"; + if(0 == tempfile_path_prefix) { + size_t dest_len = strlen(filename) + strlen(tempfile_suffix) + 1; + if(0 == (*tempfilename = safe_malloc_(dest_len))) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + local_snprintf(*tempfilename, dest_len, "%s%s", filename, tempfile_suffix); + } + else { + const char *p = strrchr(filename, '/'); + size_t dest_len; + if(0 == p) + p = filename; + else + p++; + + dest_len = strlen(tempfile_path_prefix) + strlen(p) + strlen(tempfile_suffix) + 2; + + if(0 == (*tempfilename = safe_malloc_(dest_len))) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + return false; + } + local_snprintf(*tempfilename, dest_len, "%s/%s%s", tempfile_path_prefix, p, tempfile_suffix); + } + + if(0 == (*tempfile = flac_fopen(*tempfilename, "w+b"))) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; + return false; + } + + return true; +} + +FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status) +{ + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != tempfile); + FLAC__ASSERT(0 != *tempfile); + FLAC__ASSERT(0 != tempfilename); + FLAC__ASSERT(0 != *tempfilename); + FLAC__ASSERT(0 != status); + + (void)fclose(*tempfile); + *tempfile = 0; + +#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ || defined __EMX__ + /* on some flavors of windows, flac_rename() will fail if the destination already exists */ + if(flac_unlink(filename) < 0) { + cleanup_tempfile_(tempfile, tempfilename); + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR; + return false; + } +#endif + + /*@@@ to fully support the tempfile_path_prefix we need to update this piece to actually copy across filesystems instead of just flac_rename(): */ + if(0 != flac_rename(*tempfilename, filename)) { + cleanup_tempfile_(tempfile, tempfilename); + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR; + return false; + } + + cleanup_tempfile_(tempfile, tempfilename); + + return true; +} + +void cleanup_tempfile_(FILE **tempfile, char **tempfilename) +{ + if(0 != *tempfile) { + (void)fclose(*tempfile); + *tempfile = 0; + } + + if(0 != *tempfilename) { + (void)flac_unlink(*tempfilename); + free(*tempfilename); + *tempfilename = 0; + } +} + +FLAC__bool get_file_stats_(const char *filename, struct flac_stat_s *stats) +{ + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != stats); + return (0 == flac_stat(filename, stats)); +} + +void set_file_stats_(const char *filename, struct flac_stat_s *stats) +{ + struct utimbuf srctime; + + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != stats); + + srctime.actime = stats->st_atime; + srctime.modtime = stats->st_mtime; + (void)flac_chmod(filename, stats->st_mode); + (void)flac_utime(filename, &srctime); +#if !defined _MSC_VER && !defined __BORLANDC__ && !defined __MINGW32__ + FLAC_CHECK_RETURN(chown(filename, stats->st_uid, -1)); + FLAC_CHECK_RETURN(chown(filename, -1, stats->st_gid)); +#endif +} + +int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence) +{ + return fseeko((FILE*)handle, (FLAC__off_t)offset, whence); +} + +FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle) +{ + return ftello((FILE*)handle); +} + +FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status) +{ + switch(status) { + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK: + return FLAC__METADATA_CHAIN_STATUS_OK; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT: + return FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE: + return FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE: + return FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE: + return FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA: + return FLAC__METADATA_CHAIN_STATUS_BAD_METADATA; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR: + return FLAC__METADATA_CHAIN_STATUS_READ_ERROR; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR: + return FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR: + return FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR: + return FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR: + return FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR: + return FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; + case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR: + default: + return FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; + } +} diff --git a/deps/flac-1.3.2/src/libFLAC/metadata_object.c b/deps/flac-1.3.2/src/libFLAC/metadata_object.c new file mode 100644 index 0000000..9cb9501 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/metadata_object.c @@ -0,0 +1,1821 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> + +#include "private/metadata.h" +#include "private/memory.h" + +#include "FLAC/assert.h" +#include "share/alloc.h" +#include "share/compat.h" + +/* Alias the first (in share/alloc.h) to the second (in src/libFLAC/memory.c). */ +#define safe_malloc_mul_2op_ safe_malloc_mul_2op_p + + +/**************************************************************************** + * + * Local routines + * + ***************************************************************************/ + +/* copy bytes: + * from = NULL && bytes = 0 + * to <- NULL + * from != NULL && bytes > 0 + * to <- copy of from + * else ASSERT + * malloc error leaves 'to' unchanged + */ +static FLAC__bool copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes) +{ + FLAC__ASSERT(to != NULL); + if (bytes > 0 && from != NULL) { + FLAC__byte *x; + if ((x = safe_malloc_(bytes)) == NULL) + return false; + memcpy(x, from, bytes); + *to = x; + } + else { + *to = 0; + } + return true; +} + +#if 0 /* UNUSED */ +/* like copy_bytes_(), but free()s the original '*to' if the copy succeeds and the original '*to' is non-NULL */ +static FLAC__bool free_copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes) +{ + FLAC__byte *copy; + FLAC__ASSERT(to != NULL); + if (copy_bytes_(©, from, bytes)) { + free(*to); + *to = copy; + return true; + } + else + return false; +} +#endif + +/* reallocate entry to 1 byte larger and add a terminating NUL */ +/* realloc() failure leaves entry unchanged */ +static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length) +{ + FLAC__byte *x = safe_realloc_add_2op_(*entry, length, /*+*/1); + if (x != NULL) { + x[length] = '\0'; + *entry = x; + return true; + } + else + return false; +} + +/* copies the NUL-terminated C-string 'from' to '*to', leaving '*to' + * unchanged if malloc fails, free()ing the original '*to' if it + * succeeds and the original '*to' was not NULL + */ +static FLAC__bool copy_cstring_(char **to, const char *from) +{ + char *copy = strdup(from); + FLAC__ASSERT(to != NULL); + if (copy) { + free(*to); + *to = copy; + return true; + } + else + return false; +} + +static FLAC__bool copy_vcentry_(FLAC__StreamMetadata_VorbisComment_Entry *to, const FLAC__StreamMetadata_VorbisComment_Entry *from) +{ + to->length = from->length; + if (from->entry == 0) { + FLAC__ASSERT(from->length == 0); + to->entry = 0; + } + else { + FLAC__byte *x; + FLAC__ASSERT(from->length > 0); + if ((x = safe_malloc_add_2op_(from->length, /*+*/1)) == NULL) + return false; + memcpy(x, from->entry, from->length); + x[from->length] = '\0'; + to->entry = x; + } + return true; +} + +static FLAC__bool copy_track_(FLAC__StreamMetadata_CueSheet_Track *to, const FLAC__StreamMetadata_CueSheet_Track *from) +{ + memcpy(to, from, sizeof(FLAC__StreamMetadata_CueSheet_Track)); + if (from->indices == 0) { + FLAC__ASSERT(from->num_indices == 0); + } + else { + FLAC__StreamMetadata_CueSheet_Index *x; + FLAC__ASSERT(from->num_indices > 0); + if ((x = safe_malloc_mul_2op_p(from->num_indices, /*times*/sizeof(FLAC__StreamMetadata_CueSheet_Index))) == NULL) + return false; + memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index)); + to->indices = x; + } + return true; +} + +static void seektable_calculate_length_(FLAC__StreamMetadata *object) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + + object->length = object->data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; +} + +static FLAC__StreamMetadata_SeekPoint *seekpoint_array_new_(unsigned num_points) +{ + FLAC__StreamMetadata_SeekPoint *object_array; + + FLAC__ASSERT(num_points > 0); + + object_array = safe_malloc_mul_2op_p(num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)); + + if (object_array != NULL) { + unsigned i; + for (i = 0; i < num_points; i++) { + object_array[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + object_array[i].stream_offset = 0; + object_array[i].frame_samples = 0; + } + } + + return object_array; +} + +static void vorbiscomment_calculate_length_(FLAC__StreamMetadata *object) +{ + unsigned i; + + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + object->length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN) / 8; + object->length += object->data.vorbis_comment.vendor_string.length; + object->length += (FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8; + for (i = 0; i < object->data.vorbis_comment.num_comments; i++) { + object->length += (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8); + object->length += object->data.vorbis_comment.comments[i].length; + } +} + +static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_new_(unsigned num_comments) +{ + FLAC__ASSERT(num_comments > 0); + + return safe_calloc_(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)); +} + +static void vorbiscomment_entry_array_delete_(FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments) +{ + unsigned i; + + FLAC__ASSERT(object_array != NULL && num_comments > 0); + + for (i = 0; i < num_comments; i++) + free(object_array[i].entry); + + free(object_array); +} + +static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_copy_(const FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments) +{ + FLAC__StreamMetadata_VorbisComment_Entry *return_array; + + FLAC__ASSERT(object_array != NULL); + FLAC__ASSERT(num_comments > 0); + + return_array = vorbiscomment_entry_array_new_(num_comments); + + if (return_array != NULL) { + unsigned i; + + for (i = 0; i < num_comments; i++) { + if (!copy_vcentry_(return_array+i, object_array+i)) { + vorbiscomment_entry_array_delete_(return_array, num_comments); + return 0; + } + } + } + + return return_array; +} + +static FLAC__bool vorbiscomment_set_entry_(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry *dest, const FLAC__StreamMetadata_VorbisComment_Entry *src, FLAC__bool copy) +{ + FLAC__byte *save; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(dest != NULL); + FLAC__ASSERT(src != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + FLAC__ASSERT((src->entry != NULL && src->length > 0) || (src->entry == NULL && src->length == 0)); + + save = dest->entry; + + if (src->entry != NULL) { + if (copy) { + /* do the copy first so that if we fail we leave the dest object untouched */ + if (!copy_vcentry_(dest, src)) + return false; + } + else { + /* we have to make sure that the string we're taking over is null-terminated */ + + /* + * Stripping the const from src->entry is OK since we're taking + * ownership of the pointer. This is a hack around a deficiency + * in the API where the same function is used for 'copy' and + * 'own', but the source entry is a const pointer. If we were + * precise, the 'own' flavor would be a separate function with a + * non-const source pointer. But it's not, so we hack away. + */ + if (!ensure_null_terminated_((FLAC__byte**)(&src->entry), src->length)) + return false; + *dest = *src; + } + } + else { + /* the src is null */ + *dest = *src; + } + + free(save); + + vorbiscomment_calculate_length_(object); + return true; +} + +static int vorbiscomment_find_entry_from_(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name, unsigned field_name_length) +{ + unsigned i; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + FLAC__ASSERT(field_name != NULL); + + for (i = offset; i < object->data.vorbis_comment.num_comments; i++) { + if (FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments[i], field_name, field_name_length)) + return (int)i; + } + + return -1; +} + +static void cuesheet_calculate_length_(FLAC__StreamMetadata *object) +{ + unsigned i; + + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + + object->length = ( + FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN + + FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN + + FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN + + FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN + ) / 8; + + object->length += object->data.cue_sheet.num_tracks * ( + FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN + + FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN + + FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN + + FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN + + FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN + ) / 8; + + for (i = 0; i < object->data.cue_sheet.num_tracks; i++) { + object->length += object->data.cue_sheet.tracks[i].num_indices * ( + FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN + + FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN + + FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN + ) / 8; + } +} + +static FLAC__StreamMetadata_CueSheet_Index *cuesheet_track_index_array_new_(unsigned num_indices) +{ + FLAC__ASSERT(num_indices > 0); + + return safe_calloc_(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)); +} + +static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks) +{ + FLAC__ASSERT(num_tracks > 0); + + return safe_calloc_(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)); +} + +static void cuesheet_track_array_delete_(FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks) +{ + unsigned i; + + FLAC__ASSERT(object_array != NULL && num_tracks > 0); + + for (i = 0; i < num_tracks; i++) { + if (object_array[i].indices != 0) { + FLAC__ASSERT(object_array[i].num_indices > 0); + free(object_array[i].indices); + } + } + + free(object_array); +} + +static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_copy_(const FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks) +{ + FLAC__StreamMetadata_CueSheet_Track *return_array; + + FLAC__ASSERT(object_array != NULL); + FLAC__ASSERT(num_tracks > 0); + + return_array = cuesheet_track_array_new_(num_tracks); + + if (return_array != NULL) { + unsigned i; + + for (i = 0; i < num_tracks; i++) { + if (!copy_track_(return_array+i, object_array+i)) { + cuesheet_track_array_delete_(return_array, num_tracks); + return 0; + } + } + } + + return return_array; +} + +static FLAC__bool cuesheet_set_track_(FLAC__StreamMetadata *object, FLAC__StreamMetadata_CueSheet_Track *dest, const FLAC__StreamMetadata_CueSheet_Track *src, FLAC__bool copy) +{ + FLAC__StreamMetadata_CueSheet_Index *save; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(dest != NULL); + FLAC__ASSERT(src != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + FLAC__ASSERT((src->indices != NULL && src->num_indices > 0) || (src->indices == NULL && src->num_indices == 0)); + + save = dest->indices; + + /* do the copy first so that if we fail we leave the object untouched */ + if (copy) { + if (!copy_track_(dest, src)) + return false; + } + else { + *dest = *src; + } + + free(save); + + cuesheet_calculate_length_(object); + return true; +} + + +/**************************************************************************** + * + * Metadata object routines + * + ***************************************************************************/ + +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type) +{ + FLAC__StreamMetadata *object; + + if (type > FLAC__MAX_METADATA_TYPE) + return 0; + + object = calloc(1, sizeof(FLAC__StreamMetadata)); + if (object != NULL) { + object->is_last = false; + object->type = type; + switch(type) { + case FLAC__METADATA_TYPE_STREAMINFO: + object->length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; + break; + case FLAC__METADATA_TYPE_PADDING: + /* calloc() took care of this for us: + object->length = 0; + */ + break; + case FLAC__METADATA_TYPE_APPLICATION: + object->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + /* calloc() took care of this for us: + object->data.application.data = 0; + */ + break; + case FLAC__METADATA_TYPE_SEEKTABLE: + /* calloc() took care of this for us: + object->length = 0; + object->data.seek_table.num_points = 0; + object->data.seek_table.points = 0; + */ + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + object->data.vorbis_comment.vendor_string.length = (unsigned)strlen(FLAC__VENDOR_STRING); + if (!copy_bytes_(&object->data.vorbis_comment.vendor_string.entry, (const FLAC__byte*)FLAC__VENDOR_STRING, object->data.vorbis_comment.vendor_string.length+1)) { + free(object); + return 0; + } + vorbiscomment_calculate_length_(object); + break; + case FLAC__METADATA_TYPE_CUESHEET: + cuesheet_calculate_length_(object); + break; + case FLAC__METADATA_TYPE_PICTURE: + object->length = ( + FLAC__STREAM_METADATA_PICTURE_TYPE_LEN + + FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN + /* empty mime_type string */ + FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN + /* empty description string */ + FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN + + FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN + + FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN + + FLAC__STREAM_METADATA_PICTURE_COLORS_LEN + + FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN + + 0 /* no data */ + ) / 8; + object->data.picture.type = FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER; + object->data.picture.mime_type = 0; + object->data.picture.description = 0; + /* calloc() took care of this for us: + object->data.picture.width = 0; + object->data.picture.height = 0; + object->data.picture.depth = 0; + object->data.picture.colors = 0; + object->data.picture.data_length = 0; + object->data.picture.data = 0; + */ + /* now initialize mime_type and description with empty strings to make things easier on the client */ + if (!copy_cstring_(&object->data.picture.mime_type, "")) { + free(object); + return 0; + } + if (!copy_cstring_((char**)(&object->data.picture.description), "")) { + free(object->data.picture.mime_type); + free(object); + return 0; + } + break; + default: + /* calloc() took care of this for us: + object->length = 0; + object->data.unknown.data = 0; + */ + break; + } + } + + return object; +} + +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object) +{ + FLAC__StreamMetadata *to; + + FLAC__ASSERT(object != NULL); + + if ((to = FLAC__metadata_object_new(object->type)) != NULL) { + to->is_last = object->is_last; + to->type = object->type; + to->length = object->length; + switch(to->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + memcpy(&to->data.stream_info, &object->data.stream_info, sizeof(FLAC__StreamMetadata_StreamInfo)); + break; + case FLAC__METADATA_TYPE_PADDING: + break; + case FLAC__METADATA_TYPE_APPLICATION: + if (to->length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) { /* underflow check */ + FLAC__metadata_object_delete(to); + return 0; + } + memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8); + if (!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) { + FLAC__metadata_object_delete(to); + return 0; + } + break; + case FLAC__METADATA_TYPE_SEEKTABLE: + to->data.seek_table.num_points = object->data.seek_table.num_points; + if (to->data.seek_table.num_points > UINT32_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) { /* overflow check */ + FLAC__metadata_object_delete(to); + return 0; + } + if (!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) { + FLAC__metadata_object_delete(to); + return 0; + } + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if (to->data.vorbis_comment.vendor_string.entry != NULL) { + free(to->data.vorbis_comment.vendor_string.entry); + to->data.vorbis_comment.vendor_string.entry = 0; + } + if (!copy_vcentry_(&to->data.vorbis_comment.vendor_string, &object->data.vorbis_comment.vendor_string)) { + FLAC__metadata_object_delete(to); + return 0; + } + if (object->data.vorbis_comment.num_comments == 0) { + to->data.vorbis_comment.comments = 0; + } + else { + to->data.vorbis_comment.comments = vorbiscomment_entry_array_copy_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments); + if (to->data.vorbis_comment.comments == NULL) { + to->data.vorbis_comment.num_comments = 0; + FLAC__metadata_object_delete(to); + return 0; + } + } + to->data.vorbis_comment.num_comments = object->data.vorbis_comment.num_comments; + break; + case FLAC__METADATA_TYPE_CUESHEET: + memcpy(&to->data.cue_sheet, &object->data.cue_sheet, sizeof(FLAC__StreamMetadata_CueSheet)); + if (object->data.cue_sheet.num_tracks == 0) { + FLAC__ASSERT(object->data.cue_sheet.tracks == NULL); + } + else { + FLAC__ASSERT(object->data.cue_sheet.tracks != 0); + to->data.cue_sheet.tracks = cuesheet_track_array_copy_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks); + if (to->data.cue_sheet.tracks == NULL) { + FLAC__metadata_object_delete(to); + return 0; + } + } + break; + case FLAC__METADATA_TYPE_PICTURE: + to->data.picture.type = object->data.picture.type; + if (!copy_cstring_(&to->data.picture.mime_type, object->data.picture.mime_type)) { + FLAC__metadata_object_delete(to); + return 0; + } + if (!copy_cstring_((char**)(&to->data.picture.description), (const char*)object->data.picture.description)) { + FLAC__metadata_object_delete(to); + return 0; + } + to->data.picture.width = object->data.picture.width; + to->data.picture.height = object->data.picture.height; + to->data.picture.depth = object->data.picture.depth; + to->data.picture.colors = object->data.picture.colors; + to->data.picture.data_length = object->data.picture.data_length; + if (!copy_bytes_((&to->data.picture.data), object->data.picture.data, object->data.picture.data_length)) { + FLAC__metadata_object_delete(to); + return 0; + } + break; + default: + if (!copy_bytes_(&to->data.unknown.data, object->data.unknown.data, object->length)) { + FLAC__metadata_object_delete(to); + return 0; + } + break; + } + } + + return to; +} + +void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object) +{ + FLAC__ASSERT(object != NULL); + + switch(object->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + case FLAC__METADATA_TYPE_PADDING: + break; + case FLAC__METADATA_TYPE_APPLICATION: + if (object->data.application.data != NULL) { + free(object->data.application.data); + object->data.application.data = NULL; + } + break; + case FLAC__METADATA_TYPE_SEEKTABLE: + if (object->data.seek_table.points != NULL) { + free(object->data.seek_table.points); + object->data.seek_table.points = NULL; + } + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if (object->data.vorbis_comment.vendor_string.entry != NULL) { + free(object->data.vorbis_comment.vendor_string.entry); + object->data.vorbis_comment.vendor_string.entry = 0; + } + if (object->data.vorbis_comment.comments != NULL) { + FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0); + vorbiscomment_entry_array_delete_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments); + object->data.vorbis_comment.comments = NULL; + object->data.vorbis_comment.num_comments = 0; + } + break; + case FLAC__METADATA_TYPE_CUESHEET: + if (object->data.cue_sheet.tracks != NULL) { + FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0); + cuesheet_track_array_delete_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks); + object->data.cue_sheet.tracks = NULL; + object->data.cue_sheet.num_tracks = 0; + } + break; + case FLAC__METADATA_TYPE_PICTURE: + if (object->data.picture.mime_type != NULL) { + free(object->data.picture.mime_type); + object->data.picture.mime_type = NULL; + } + if (object->data.picture.description != NULL) { + free(object->data.picture.description); + object->data.picture.description = NULL; + } + if (object->data.picture.data != NULL) { + free(object->data.picture.data); + object->data.picture.data = NULL; + } + break; + default: + if (object->data.unknown.data != NULL) { + free(object->data.unknown.data); + object->data.unknown.data = NULL; + } + break; + } +} + +FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object) +{ + FLAC__metadata_object_delete_data(object); + free(object); +} + +static FLAC__bool compare_block_data_streaminfo_(const FLAC__StreamMetadata_StreamInfo *block1, const FLAC__StreamMetadata_StreamInfo *block2) +{ + if (block1->min_blocksize != block2->min_blocksize) + return false; + if (block1->max_blocksize != block2->max_blocksize) + return false; + if (block1->min_framesize != block2->min_framesize) + return false; + if (block1->max_framesize != block2->max_framesize) + return false; + if (block1->sample_rate != block2->sample_rate) + return false; + if (block1->channels != block2->channels) + return false; + if (block1->bits_per_sample != block2->bits_per_sample) + return false; + if (block1->total_samples != block2->total_samples) + return false; + if (memcmp(block1->md5sum, block2->md5sum, 16) != 0) + return false; + return true; +} + +static FLAC__bool compare_block_data_application_(const FLAC__StreamMetadata_Application *block1, const FLAC__StreamMetadata_Application *block2, unsigned block_length) +{ + FLAC__ASSERT(block1 != NULL); + FLAC__ASSERT(block2 != NULL); + FLAC__ASSERT(block_length >= sizeof(block1->id)); + + if (memcmp(block1->id, block2->id, sizeof(block1->id)) != 0) + return false; + if (block1->data != NULL && block2->data != NULL) + return memcmp(block1->data, block2->data, block_length - sizeof(block1->id)) == 0; + else + return block1->data == block2->data; +} + +static FLAC__bool compare_block_data_seektable_(const FLAC__StreamMetadata_SeekTable *block1, const FLAC__StreamMetadata_SeekTable *block2) +{ + unsigned i; + + FLAC__ASSERT(block1 != NULL); + FLAC__ASSERT(block2 != NULL); + + if (block1->num_points != block2->num_points) + return false; + + if (block1->points != NULL && block2->points != NULL) { + for (i = 0; i < block1->num_points; i++) { + if (block1->points[i].sample_number != block2->points[i].sample_number) + return false; + if (block1->points[i].stream_offset != block2->points[i].stream_offset) + return false; + if (block1->points[i].frame_samples != block2->points[i].frame_samples) + return false; + } + return true; + } + else + return block1->points == block2->points; +} + +static FLAC__bool compare_block_data_vorbiscomment_(const FLAC__StreamMetadata_VorbisComment *block1, const FLAC__StreamMetadata_VorbisComment *block2) +{ + unsigned i; + + if (block1->vendor_string.length != block2->vendor_string.length) + return false; + + if (block1->vendor_string.entry != NULL && block2->vendor_string.entry != NULL) { + if (memcmp(block1->vendor_string.entry, block2->vendor_string.entry, block1->vendor_string.length) != 0) + return false; + } + else if (block1->vendor_string.entry != block2->vendor_string.entry) + return false; + + if (block1->num_comments != block2->num_comments) + return false; + + for (i = 0; i < block1->num_comments; i++) { + if (block1->comments[i].entry != NULL && block2->comments[i].entry != NULL) { + if (memcmp(block1->comments[i].entry, block2->comments[i].entry, block1->comments[i].length) != 0) + return false; + } + else if (block1->comments[i].entry != block2->comments[i].entry) + return false; + } + return true; +} + +static FLAC__bool compare_block_data_cuesheet_(const FLAC__StreamMetadata_CueSheet *block1, const FLAC__StreamMetadata_CueSheet *block2) +{ + unsigned i, j; + + if (strcmp(block1->media_catalog_number, block2->media_catalog_number) != 0) + return false; + + if (block1->lead_in != block2->lead_in) + return false; + + if (block1->is_cd != block2->is_cd) + return false; + + if (block1->num_tracks != block2->num_tracks) + return false; + + if (block1->tracks != NULL && block2->tracks != NULL) { + FLAC__ASSERT(block1->num_tracks > 0); + for (i = 0; i < block1->num_tracks; i++) { + if (block1->tracks[i].offset != block2->tracks[i].offset) + return false; + if (block1->tracks[i].number != block2->tracks[i].number) + return false; + if (memcmp(block1->tracks[i].isrc, block2->tracks[i].isrc, sizeof(block1->tracks[i].isrc)) != 0) + return false; + if (block1->tracks[i].type != block2->tracks[i].type) + return false; + if (block1->tracks[i].pre_emphasis != block2->tracks[i].pre_emphasis) + return false; + if (block1->tracks[i].num_indices != block2->tracks[i].num_indices) + return false; + if (block1->tracks[i].indices != NULL && block2->tracks[i].indices != NULL) { + FLAC__ASSERT(block1->tracks[i].num_indices > 0); + for (j = 0; j < block1->tracks[i].num_indices; j++) { + if (block1->tracks[i].indices[j].offset != block2->tracks[i].indices[j].offset) + return false; + if (block1->tracks[i].indices[j].number != block2->tracks[i].indices[j].number) + return false; + } + } + else if (block1->tracks[i].indices != block2->tracks[i].indices) + return false; + } + } + else if (block1->tracks != block2->tracks) + return false; + return true; +} + +static FLAC__bool compare_block_data_picture_(const FLAC__StreamMetadata_Picture *block1, const FLAC__StreamMetadata_Picture *block2) +{ + if (block1->type != block2->type) + return false; + if (block1->mime_type != block2->mime_type && (block1->mime_type == 0 || block2->mime_type == 0 || strcmp(block1->mime_type, block2->mime_type))) + return false; + if (block1->description != block2->description && (block1->description == 0 || block2->description == 0 || strcmp((const char *)block1->description, (const char *)block2->description))) + return false; + if (block1->width != block2->width) + return false; + if (block1->height != block2->height) + return false; + if (block1->depth != block2->depth) + return false; + if (block1->colors != block2->colors) + return false; + if (block1->data_length != block2->data_length) + return false; + if (block1->data != block2->data && (block1->data == NULL || block2->data == NULL || memcmp(block1->data, block2->data, block1->data_length))) + return false; + return true; +} + +static FLAC__bool compare_block_data_unknown_(const FLAC__StreamMetadata_Unknown *block1, const FLAC__StreamMetadata_Unknown *block2, unsigned block_length) +{ + FLAC__ASSERT(block1 != NULL); + FLAC__ASSERT(block2 != NULL); + + if (block1->data != NULL && block2->data != NULL) + return memcmp(block1->data, block2->data, block_length) == 0; + else + return block1->data == block2->data; +} + +FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2) +{ + FLAC__ASSERT(block1 != NULL); + FLAC__ASSERT(block2 != NULL); + + if (block1->type != block2->type) { + return false; + } + if (block1->is_last != block2->is_last) { + return false; + } + if (block1->length != block2->length) { + return false; + } + switch(block1->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + return compare_block_data_streaminfo_(&block1->data.stream_info, &block2->data.stream_info); + case FLAC__METADATA_TYPE_PADDING: + return true; /* we don't compare the padding guts */ + case FLAC__METADATA_TYPE_APPLICATION: + return compare_block_data_application_(&block1->data.application, &block2->data.application, block1->length); + case FLAC__METADATA_TYPE_SEEKTABLE: + return compare_block_data_seektable_(&block1->data.seek_table, &block2->data.seek_table); + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + return compare_block_data_vorbiscomment_(&block1->data.vorbis_comment, &block2->data.vorbis_comment); + case FLAC__METADATA_TYPE_CUESHEET: + return compare_block_data_cuesheet_(&block1->data.cue_sheet, &block2->data.cue_sheet); + case FLAC__METADATA_TYPE_PICTURE: + return compare_block_data_picture_(&block1->data.picture, &block2->data.picture); + default: + return compare_block_data_unknown_(&block1->data.unknown, &block2->data.unknown, block1->length); + } +} + +FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy) +{ + FLAC__byte *save; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_APPLICATION); + FLAC__ASSERT((data != NULL && length > 0) || (data == NULL && length == 0 && copy == false)); + + save = object->data.application.data; + + /* do the copy first so that if we fail we leave the object untouched */ + if (copy) { + if (!copy_bytes_(&object->data.application.data, data, length)) + return false; + } + else { + object->data.application.data = data; + } + + free(save); + + object->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 + length; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + + if (object->data.seek_table.points == 0) { + FLAC__ASSERT(object->data.seek_table.num_points == 0); + if (new_num_points == 0) + return true; + else if ((object->data.seek_table.points = seekpoint_array_new_(new_num_points)) == 0) + return false; + } + else { + const size_t old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint); + const size_t new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint); + + /* overflow check */ + if (new_num_points > UINT32_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) + return false; + + FLAC__ASSERT(object->data.seek_table.num_points > 0); + + if (new_size == 0) { + free(object->data.seek_table.points); + object->data.seek_table.points = 0; + } + else if ((object->data.seek_table.points = safe_realloc_(object->data.seek_table.points, new_size)) == NULL) + return false; + + /* if growing, set new elements to placeholders */ + if (new_size > old_size) { + unsigned i; + for (i = object->data.seek_table.num_points; i < new_num_points; i++) { + object->data.seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + object->data.seek_table.points[i].stream_offset = 0; + object->data.seek_table.points[i].frame_samples = 0; + } + } + } + + object->data.seek_table.num_points = new_num_points; + + seektable_calculate_length_(object); + return true; +} + +FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + FLAC__ASSERT(point_num < object->data.seek_table.num_points); + + object->data.seek_table.points[point_num] = point; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point) +{ + int i; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + FLAC__ASSERT(point_num <= object->data.seek_table.num_points); + + if (!FLAC__metadata_object_seektable_resize_points(object, object->data.seek_table.num_points+1)) + return false; + + /* move all points >= point_num forward one space */ + for (i = (int)object->data.seek_table.num_points-1; i > (int)point_num; i--) + object->data.seek_table.points[i] = object->data.seek_table.points[i-1]; + + FLAC__metadata_object_seektable_set_point(object, point_num, point); + seektable_calculate_length_(object); + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num) +{ + unsigned i; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + FLAC__ASSERT(point_num < object->data.seek_table.num_points); + + /* move all points > point_num backward one space */ + for (i = point_num; i < object->data.seek_table.num_points-1; i++) + object->data.seek_table.points[i] = object->data.seek_table.points[i+1]; + + return FLAC__metadata_object_seektable_resize_points(object, object->data.seek_table.num_points-1); +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + + return FLAC__format_seektable_is_legal(&object->data.seek_table); +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + + if (num > 0) + /* WATCHOUT: we rely on the fact that growing the array adds PLACEHOLDERS at the end */ + return FLAC__metadata_object_seektable_resize_points(object, object->data.seek_table.num_points + num); + else + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number) +{ + FLAC__StreamMetadata_SeekTable *seek_table; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + + seek_table = &object->data.seek_table; + + if (!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + 1)) + return false; + + seek_table->points[seek_table->num_points - 1].sample_number = sample_number; + seek_table->points[seek_table->num_points - 1].stream_offset = 0; + seek_table->points[seek_table->num_points - 1].frame_samples = 0; + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + FLAC__ASSERT(sample_numbers != 0 || num == 0); + + if (num > 0) { + FLAC__StreamMetadata_SeekTable *seek_table = &object->data.seek_table; + unsigned i, j; + + i = seek_table->num_points; + + if (!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + num)) + return false; + + for (j = 0; j < num; i++, j++) { + seek_table->points[i].sample_number = sample_numbers[j]; + seek_table->points[i].stream_offset = 0; + seek_table->points[i].frame_samples = 0; + } + } + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + FLAC__ASSERT(total_samples > 0); + + if (num > 0 && total_samples > 0) { + FLAC__StreamMetadata_SeekTable *seek_table = &object->data.seek_table; + unsigned i, j; + + i = seek_table->num_points; + + if (!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + num)) + return false; + + for (j = 0; j < num; i++, j++) { + seek_table->points[i].sample_number = total_samples * (FLAC__uint64)j / (FLAC__uint64)num; + seek_table->points[i].stream_offset = 0; + seek_table->points[i].frame_samples = 0; + } + } + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + FLAC__ASSERT(samples > 0); + FLAC__ASSERT(total_samples > 0); + + if (samples > 0 && total_samples > 0) { + FLAC__StreamMetadata_SeekTable *seek_table = &object->data.seek_table; + unsigned i, j; + FLAC__uint64 num, sample; + + num = 1 + total_samples / samples; /* 1+ for the first sample at 0 */ + /* now account for the fact that we don't place a seekpoint at "total_samples" since samples are number from 0: */ + if (total_samples % samples == 0) + num--; + + /* Put a strict upper bound on the number of allowed seek points. */ + if (num > 32768) { + /* Set the bound and recalculate samples accordingly. */ + num = 32768; + samples = total_samples / num; + } + + i = seek_table->num_points; + + if (!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + (unsigned)num)) + return false; + + sample = 0; + for (j = 0; j < num; i++, j++, sample += samples) { + seek_table->points[i].sample_number = sample; + seek_table->points[i].stream_offset = 0; + seek_table->points[i].frame_samples = 0; + } + } + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact) +{ + unsigned unique; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); + + unique = FLAC__format_seektable_sort(&object->data.seek_table); + + return !compact || FLAC__metadata_object_seektable_resize_points(object, unique); +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) +{ + if (!FLAC__format_vorbiscomment_entry_value_is_legal(entry.entry, entry.length)) + return false; + return vorbiscomment_set_entry_(object, &object->data.vorbis_comment.vendor_string, &entry, copy); +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + if (object->data.vorbis_comment.comments == NULL) { + FLAC__ASSERT(object->data.vorbis_comment.num_comments == 0); + if (new_num_comments == 0) + return true; + else if ((object->data.vorbis_comment.comments = vorbiscomment_entry_array_new_(new_num_comments)) == NULL) + return false; + } + else { + const size_t old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); + const size_t new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); + + /* overflow check */ + if (new_num_comments > UINT32_MAX / sizeof(FLAC__StreamMetadata_VorbisComment_Entry)) + return false; + + FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0); + + /* if shrinking, free the truncated entries */ + if (new_num_comments < object->data.vorbis_comment.num_comments) { + unsigned i; + for (i = new_num_comments; i < object->data.vorbis_comment.num_comments; i++) + if (object->data.vorbis_comment.comments[i].entry != NULL) + free(object->data.vorbis_comment.comments[i].entry); + } + + if (new_size == 0) { + free(object->data.vorbis_comment.comments); + object->data.vorbis_comment.comments = 0; + } + else { + FLAC__StreamMetadata_VorbisComment_Entry *oldptr = object->data.vorbis_comment.comments; + if ((object->data.vorbis_comment.comments = realloc(object->data.vorbis_comment.comments, new_size)) == NULL) { + vorbiscomment_entry_array_delete_(oldptr, object->data.vorbis_comment.num_comments); + object->data.vorbis_comment.num_comments = 0; + return false; + } + } + + /* if growing, zero all the length/pointers of new elements */ + if (new_size > old_size) + memset(object->data.vorbis_comment.comments + object->data.vorbis_comment.num_comments, 0, new_size - old_size); + } + + object->data.vorbis_comment.num_comments = new_num_comments; + + vorbiscomment_calculate_length_(object); + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(comment_num < object->data.vorbis_comment.num_comments); + + if (!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) + return false; + return vorbiscomment_set_entry_(object, &object->data.vorbis_comment.comments[comment_num], &entry, copy); +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) +{ + FLAC__StreamMetadata_VorbisComment *vc; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + FLAC__ASSERT(comment_num <= object->data.vorbis_comment.num_comments); + + if (!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) + return false; + + vc = &object->data.vorbis_comment; + + if (!FLAC__metadata_object_vorbiscomment_resize_comments(object, vc->num_comments+1)) + return false; + + /* move all comments >= comment_num forward one space */ + memmove(&vc->comments[comment_num+1], &vc->comments[comment_num], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(vc->num_comments-1-comment_num)); + vc->comments[comment_num].length = 0; + vc->comments[comment_num].entry = 0; + + return FLAC__metadata_object_vorbiscomment_set_comment(object, comment_num, entry, copy); +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + return FLAC__metadata_object_vorbiscomment_insert_comment(object, object->data.vorbis_comment.num_comments, entry, copy); +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy) +{ + FLAC__ASSERT(entry.entry != NULL && entry.length > 0); + + if (!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) + return false; + + { + int i; + size_t field_name_length; + const FLAC__byte *eq = (FLAC__byte*)memchr(entry.entry, '=', entry.length); + + if (eq == NULL) + return false; /* double protection */ + + field_name_length = eq-entry.entry; + + i = vorbiscomment_find_entry_from_(object, 0, (const char *)entry.entry, field_name_length); + if (i >= 0) { + unsigned indx = (unsigned)i; + if (!FLAC__metadata_object_vorbiscomment_set_comment(object, indx, entry, copy)) + return false; + entry = object->data.vorbis_comment.comments[indx]; + indx++; /* skip over replaced comment */ + if (all && indx < object->data.vorbis_comment.num_comments) { + i = vorbiscomment_find_entry_from_(object, indx, (const char *)entry.entry, field_name_length); + while (i >= 0) { + indx = (unsigned)i; + if (!FLAC__metadata_object_vorbiscomment_delete_comment(object, indx)) + return false; + if (indx < object->data.vorbis_comment.num_comments) + i = vorbiscomment_find_entry_from_(object, indx, (const char *)entry.entry, field_name_length); + else + i = -1; + } + } + return true; + } + else + return FLAC__metadata_object_vorbiscomment_append_comment(object, entry, copy); + } +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num) +{ + FLAC__StreamMetadata_VorbisComment *vc; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + FLAC__ASSERT(comment_num < object->data.vorbis_comment.num_comments); + + vc = &object->data.vorbis_comment; + + /* free the comment at comment_num */ + free(vc->comments[comment_num].entry); + + /* move all comments > comment_num backward one space */ + memmove(&vc->comments[comment_num], &vc->comments[comment_num+1], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(vc->num_comments-comment_num-1)); + vc->comments[vc->num_comments-1].length = 0; + vc->comments[vc->num_comments-1].entry = 0; + + return FLAC__metadata_object_vorbiscomment_resize_comments(object, vc->num_comments-1); +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value) +{ + FLAC__ASSERT(entry != NULL); + FLAC__ASSERT(field_name != NULL); + FLAC__ASSERT(field_value != NULL); + + if (!FLAC__format_vorbiscomment_entry_name_is_legal(field_name)) + return false; + if (!FLAC__format_vorbiscomment_entry_value_is_legal((const FLAC__byte *)field_value, (unsigned)(-1))) + return false; + + { + const size_t nn = strlen(field_name); + const size_t nv = strlen(field_value); + entry->length = nn + 1 /*=*/ + nv; + if ((entry->entry = safe_malloc_add_4op_(nn, /*+*/1, /*+*/nv, /*+*/1)) == NULL) + return false; + memcpy(entry->entry, field_name, nn); + entry->entry[nn] = '='; + memcpy(entry->entry+nn+1, field_value, nv); + entry->entry[entry->length] = '\0'; + } + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value) +{ + FLAC__ASSERT(entry.entry != NULL && entry.length > 0); + FLAC__ASSERT(field_name != NULL); + FLAC__ASSERT(field_value != NULL); + + if (!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) + return false; + + { + const FLAC__byte *eq = (FLAC__byte*)memchr(entry.entry, '=', entry.length); + const size_t nn = eq-entry.entry; + const size_t nv = entry.length-nn-1; /* -1 for the '=' */ + + if (eq == NULL) + return false; /* double protection */ + if ((*field_name = safe_malloc_add_2op_(nn, /*+*/1)) == NULL) + return false; + if ((*field_value = safe_malloc_add_2op_(nv, /*+*/1)) == NULL) { + free(*field_name); + return false; + } + memcpy(*field_name, entry.entry, nn); + memcpy(*field_value, entry.entry+nn+1, nv); + (*field_name)[nn] = '\0'; + (*field_value)[nv] = '\0'; + } + + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length) +{ + FLAC__ASSERT(entry.entry != NULL && entry.length > 0); + { + const FLAC__byte *eq = (FLAC__byte*)memchr(entry.entry, '=', entry.length); + return (eq != NULL && (unsigned)(eq-entry.entry) == field_name_length && FLAC__STRNCASECMP(field_name, (const char *)entry.entry, field_name_length) == 0); + } +} + +FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name) +{ + FLAC__ASSERT(field_name != NULL); + + return vorbiscomment_find_entry_from_(object, offset, field_name, strlen(field_name)); +} + +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name) +{ + const unsigned field_name_length = strlen(field_name); + unsigned i; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + for (i = 0; i < object->data.vorbis_comment.num_comments; i++) { + if (FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments[i], field_name, field_name_length)) { + if (!FLAC__metadata_object_vorbiscomment_delete_comment(object, i)) + return -1; + else + return 1; + } + } + + return 0; +} + +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name) +{ + FLAC__bool ok = true; + unsigned matching = 0; + const unsigned field_name_length = strlen(field_name); + int i; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + /* must delete from end to start otherwise it will interfere with our iteration */ + for (i = (int)object->data.vorbis_comment.num_comments - 1; ok && i >= 0; i--) { + if (FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments[i], field_name, field_name_length)) { + matching++; + ok &= FLAC__metadata_object_vorbiscomment_delete_comment(object, (unsigned)i); + } + } + + return ok? (int)matching : -1; +} + +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void) +{ + return calloc(1, sizeof(FLAC__StreamMetadata_CueSheet_Track)); +} + +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object) +{ + FLAC__StreamMetadata_CueSheet_Track *to; + + FLAC__ASSERT(object != NULL); + + if ((to = FLAC__metadata_object_cuesheet_track_new()) != NULL) { + if (!copy_track_(to, object)) { + FLAC__metadata_object_cuesheet_track_delete(to); + return 0; + } + } + + return to; +} + +void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object) +{ + FLAC__ASSERT(object != NULL); + + if (object->indices != NULL) { + FLAC__ASSERT(object->num_indices > 0); + free(object->indices); + } +} + +FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object) +{ + FLAC__metadata_object_cuesheet_track_delete_data(object); + free(object); +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices) +{ + FLAC__StreamMetadata_CueSheet_Track *track; + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); + + track = &object->data.cue_sheet.tracks[track_num]; + + if (track->indices == NULL) { + FLAC__ASSERT(track->num_indices == 0); + if (new_num_indices == 0) + return true; + else if ((track->indices = cuesheet_track_index_array_new_(new_num_indices)) == NULL) + return false; + } + else { + const size_t old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); + const size_t new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); + + /* overflow check */ + if (new_num_indices > UINT32_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Index)) + return false; + + FLAC__ASSERT(track->num_indices > 0); + + if (new_size == 0) { + free(track->indices); + track->indices = 0; + } + else if ((track->indices = safe_realloc_(track->indices, new_size)) == NULL) + return false; + + /* if growing, zero all the lengths/pointers of new elements */ + if (new_size > old_size) + memset(track->indices + track->num_indices, 0, new_size - old_size); + } + + track->num_indices = new_num_indices; + + cuesheet_calculate_length_(object); + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index indx) +{ + FLAC__StreamMetadata_CueSheet_Track *track; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); + FLAC__ASSERT(index_num <= object->data.cue_sheet.tracks[track_num].num_indices); + + track = &object->data.cue_sheet.tracks[track_num]; + + if (!FLAC__metadata_object_cuesheet_track_resize_indices(object, track_num, track->num_indices+1)) + return false; + + /* move all indices >= index_num forward one space */ + memmove(&track->indices[index_num+1], &track->indices[index_num], sizeof(FLAC__StreamMetadata_CueSheet_Index)*(track->num_indices-1-index_num)); + + track->indices[index_num] = indx; + cuesheet_calculate_length_(object); + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num) +{ + FLAC__StreamMetadata_CueSheet_Index indx; + memset(&indx, 0, sizeof(indx)); + return FLAC__metadata_object_cuesheet_track_insert_index(object, track_num, index_num, indx); +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num) +{ + FLAC__StreamMetadata_CueSheet_Track *track; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); + FLAC__ASSERT(index_num < object->data.cue_sheet.tracks[track_num].num_indices); + + track = &object->data.cue_sheet.tracks[track_num]; + + /* move all indices > index_num backward one space */ + memmove(&track->indices[index_num], &track->indices[index_num+1], sizeof(FLAC__StreamMetadata_CueSheet_Index)*(track->num_indices-index_num-1)); + + FLAC__metadata_object_cuesheet_track_resize_indices(object, track_num, track->num_indices-1); + cuesheet_calculate_length_(object); + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + + if (object->data.cue_sheet.tracks == NULL) { + FLAC__ASSERT(object->data.cue_sheet.num_tracks == 0); + if (new_num_tracks == 0) + return true; + else if ((object->data.cue_sheet.tracks = cuesheet_track_array_new_(new_num_tracks)) == NULL) + return false; + } + else { + const size_t old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); + const size_t new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); + + /* overflow check */ + if (new_num_tracks > UINT32_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Track)) + return false; + + FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0); + + /* if shrinking, free the truncated entries */ + if (new_num_tracks < object->data.cue_sheet.num_tracks) { + unsigned i; + for (i = new_num_tracks; i < object->data.cue_sheet.num_tracks; i++) + free(object->data.cue_sheet.tracks[i].indices); + } + + if (new_size == 0) { + free(object->data.cue_sheet.tracks); + object->data.cue_sheet.tracks = 0; + } + else if ((object->data.cue_sheet.tracks = safe_realloc_(object->data.cue_sheet.tracks, new_size)) == NULL) + return false; + + /* if growing, zero all the lengths/pointers of new elements */ + if (new_size > old_size) + memset(object->data.cue_sheet.tracks + object->data.cue_sheet.num_tracks, 0, new_size - old_size); + } + + object->data.cue_sheet.num_tracks = new_num_tracks; + + cuesheet_calculate_length_(object); + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); + + return cuesheet_set_track_(object, object->data.cue_sheet.tracks + track_num, track, copy); +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy) +{ + FLAC__StreamMetadata_CueSheet *cs; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + FLAC__ASSERT(track_num <= object->data.cue_sheet.num_tracks); + + cs = &object->data.cue_sheet; + + if (!FLAC__metadata_object_cuesheet_resize_tracks(object, cs->num_tracks+1)) + return false; + + /* move all tracks >= track_num forward one space */ + memmove(&cs->tracks[track_num+1], &cs->tracks[track_num], sizeof(FLAC__StreamMetadata_CueSheet_Track)*(cs->num_tracks-1-track_num)); + cs->tracks[track_num].num_indices = 0; + cs->tracks[track_num].indices = 0; + + return FLAC__metadata_object_cuesheet_set_track(object, track_num, track, copy); +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num) +{ + FLAC__StreamMetadata_CueSheet_Track track; + memset(&track, 0, sizeof(track)); + return FLAC__metadata_object_cuesheet_insert_track(object, track_num, &track, /*copy=*/false); +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num) +{ + FLAC__StreamMetadata_CueSheet *cs; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); + + cs = &object->data.cue_sheet; + + /* free the track at track_num */ + free(cs->tracks[track_num].indices); + + /* move all tracks > track_num backward one space */ + memmove(&cs->tracks[track_num], &cs->tracks[track_num+1], sizeof(FLAC__StreamMetadata_CueSheet_Track)*(cs->num_tracks-track_num-1)); + cs->tracks[cs->num_tracks-1].num_indices = 0; + cs->tracks[cs->num_tracks-1].indices = 0; + + return FLAC__metadata_object_cuesheet_resize_tracks(object, cs->num_tracks-1); +} + +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + + return FLAC__format_cuesheet_is_legal(&object->data.cue_sheet, check_cd_da_subset, violation); +} + +static FLAC__uint64 get_index_01_offset_(const FLAC__StreamMetadata_CueSheet *cs, unsigned track) +{ + if (track >= (cs->num_tracks-1) || cs->tracks[track].num_indices < 1) + return 0; + else if (cs->tracks[track].indices[0].number == 1) + return cs->tracks[track].indices[0].offset + cs->tracks[track].offset + cs->lead_in; + else if (cs->tracks[track].num_indices < 2) + return 0; + else if (cs->tracks[track].indices[1].number == 1) + return cs->tracks[track].indices[1].offset + cs->tracks[track].offset + cs->lead_in; + else + return 0; +} + +static FLAC__uint32 cddb_add_digits_(FLAC__uint32 x) +{ + FLAC__uint32 n = 0; + while (x) { + n += (x%10); + x /= 10; + } + return n; +} + +/*@@@@add to tests*/ +FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object) +{ + const FLAC__StreamMetadata_CueSheet *cs; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); + + cs = &object->data.cue_sheet; + + if (cs->num_tracks < 2) /* need at least one real track and the lead-out track */ + return 0; + + { + FLAC__uint32 i, length, sum = 0; + for (i = 0; i < (cs->num_tracks-1); i++) /* -1 to avoid counting the lead-out */ + sum += cddb_add_digits_((FLAC__uint32)(get_index_01_offset_(cs, i) / 44100)); + length = (FLAC__uint32)((cs->tracks[cs->num_tracks-1].offset+cs->lead_in) / 44100) - (FLAC__uint32)(get_index_01_offset_(cs, 0) / 44100); + + return (sum % 0xFF) << 24 | length << 8 | (FLAC__uint32)(cs->num_tracks-1); + } +} + +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy) +{ + char *old; + size_t old_length, new_length; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_PICTURE); + FLAC__ASSERT(mime_type != NULL); + + old = object->data.picture.mime_type; + old_length = old? strlen(old) : 0; + new_length = strlen(mime_type); + + /* do the copy first so that if we fail we leave the object untouched */ + if (copy) { + if (new_length >= SIZE_MAX) /* overflow check */ + return false; + if (!copy_bytes_((FLAC__byte**)(&object->data.picture.mime_type), (FLAC__byte*)mime_type, new_length+1)) + return false; + } + else { + object->data.picture.mime_type = mime_type; + } + + free(old); + + object->length -= old_length; + object->length += new_length; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy) +{ + FLAC__byte *old; + size_t old_length, new_length; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_PICTURE); + FLAC__ASSERT(description != NULL); + + old = object->data.picture.description; + old_length = old? strlen((const char *)old) : 0; + new_length = strlen((const char *)description); + + /* do the copy first so that if we fail we leave the object untouched */ + if (copy) { + if (new_length >= SIZE_MAX) /* overflow check */ + return false; + if (!copy_bytes_(&object->data.picture.description, description, new_length+1)) + return false; + } + else { + object->data.picture.description = description; + } + + free(old); + + object->length -= old_length; + object->length += new_length; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy) +{ + FLAC__byte *old; + + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_PICTURE); + FLAC__ASSERT((data != NULL && length > 0) || (data == NULL && length == 0 && copy == false)); + + old = object->data.picture.data; + + /* do the copy first so that if we fail we leave the object untouched */ + if (copy) { + if (!copy_bytes_(&object->data.picture.data, data, length)) + return false; + } + else { + object->data.picture.data = data; + } + + free(old); + + object->length -= object->data.picture.data_length; + object->data.picture.data_length = length; + object->length += length; + return true; +} + +FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation) +{ + FLAC__ASSERT(object != NULL); + FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_PICTURE); + + return FLAC__format_picture_is_legal(&object->data.picture, violation); +} diff --git a/deps/flac-1.3.2/src/libFLAC/ogg_decoder_aspect.c b/deps/flac-1.3.2/src/libFLAC/ogg_decoder_aspect.c new file mode 100644 index 0000000..40cee19 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ogg_decoder_aspect.c @@ -0,0 +1,251 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> /* for memcpy() */ +#include "FLAC/assert.h" +#include "private/ogg_decoder_aspect.h" +#include "private/ogg_mapping.h" +#include "private/macros.h" + + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect) +{ + /* we will determine the serial number later if necessary */ + if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0) + return false; + + if(ogg_sync_init(&aspect->sync_state) != 0) + return false; + + aspect->version_major = ~(0u); + aspect->version_minor = ~(0u); + + aspect->need_serial_number = aspect->use_first_serial_number; + + aspect->end_of_stream = false; + aspect->have_working_page = false; + + return true; +} + +void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect) +{ + (void)ogg_sync_clear(&aspect->sync_state); + (void)ogg_stream_clear(&aspect->stream_state); +} + +void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value) +{ + aspect->use_first_serial_number = false; + aspect->serial_number = value; +} + +void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect) +{ + aspect->use_first_serial_number = true; +} + +void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect) +{ + (void)ogg_stream_reset(&aspect->stream_state); + (void)ogg_sync_reset(&aspect->sync_state); + aspect->end_of_stream = false; + aspect->have_working_page = false; +} + +void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect) +{ + FLAC__ogg_decoder_aspect_flush(aspect); + + if(aspect->use_first_serial_number) + aspect->need_serial_number = true; +} + +FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data) +{ + static const size_t OGG_BYTES_CHUNK = 8192; + const size_t bytes_requested = *bytes; + + /* + * The FLAC decoding API uses pull-based reads, whereas Ogg decoding + * is push-based. In libFLAC, when you ask to decode a frame, the + * decoder will eventually call the read callback to supply some data, + * but how much it asks for depends on how much free space it has in + * its internal buffer. It does not try to grow its internal buffer + * to accomodate a whole frame because then the internal buffer size + * could not be limited, which is necessary in embedded applications. + * + * Ogg however grows its internal buffer until a whole page is present; + * only then can you get decoded data out. So we can't just ask for + * the same number of bytes from Ogg, then pass what's decoded down to + * libFLAC. If what libFLAC is asking for will not contain a whole + * page, then we will get no data from ogg_sync_pageout(), and at the + * same time cannot just read more data from the client for the purpose + * of getting a whole decoded page because the decoded size might be + * larger than libFLAC's internal buffer. + * + * Instead, whenever this read callback wrapper is called, we will + * continually request data from the client until we have at least one + * page, and manage pages internally so that we can send pieces of + * pages down to libFLAC in such a way that we obey its size + * requirement. To limit the amount of callbacks, we will always try + * to read in enough pages to return the full number of bytes + * requested. + */ + *bytes = 0; + while (*bytes < bytes_requested && !aspect->end_of_stream) { + if (aspect->have_working_page) { + if (aspect->have_working_packet) { + size_t n = bytes_requested - *bytes; + if ((size_t)aspect->working_packet.bytes <= n) { + /* the rest of the packet will fit in the buffer */ + n = aspect->working_packet.bytes; + memcpy(buffer, aspect->working_packet.packet, n); + *bytes += n; + buffer += n; + aspect->have_working_packet = false; + } + else { + /* only n bytes of the packet will fit in the buffer */ + memcpy(buffer, aspect->working_packet.packet, n); + *bytes += n; + buffer += n; + aspect->working_packet.packet += n; + aspect->working_packet.bytes -= n; + } + } + else { + /* try and get another packet */ + const int ret = ogg_stream_packetout(&aspect->stream_state, &aspect->working_packet); + if (ret > 0) { + aspect->have_working_packet = true; + /* if it is the first header packet, check for magic and a supported Ogg FLAC mapping version */ + if (aspect->working_packet.bytes > 0 && aspect->working_packet.packet[0] == FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE) { + const FLAC__byte *b = aspect->working_packet.packet; + const unsigned header_length = + FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + + FLAC__OGG_MAPPING_MAGIC_LENGTH + + FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + + FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + + FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH; + if (aspect->working_packet.bytes < (long)header_length) + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC; + b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH; + if (memcmp(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH)) + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC; + b += FLAC__OGG_MAPPING_MAGIC_LENGTH; + aspect->version_major = (unsigned)(*b); + b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH; + aspect->version_minor = (unsigned)(*b); + if (aspect->version_major != 1) + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION; + aspect->working_packet.packet += header_length; + aspect->working_packet.bytes -= header_length; + } + } + else if (ret == 0) { + aspect->have_working_page = false; + } + else { /* ret < 0 */ + /* lost sync, we'll leave the working page for the next call */ + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC; + } + } + } + else { + /* try and get another page */ + const int ret = ogg_sync_pageout(&aspect->sync_state, &aspect->working_page); + if (ret > 0) { + /* got a page, grab the serial number if necessary */ + if(aspect->need_serial_number) { + aspect->stream_state.serialno = aspect->serial_number = ogg_page_serialno(&aspect->working_page); + aspect->need_serial_number = false; + } + if(ogg_stream_pagein(&aspect->stream_state, &aspect->working_page) == 0) { + aspect->have_working_page = true; + aspect->have_working_packet = false; + } + /* else do nothing, could be a page from another stream */ + } + else if (ret == 0) { + /* need more data */ + const size_t ogg_bytes_to_read = flac_max(bytes_requested - *bytes, OGG_BYTES_CHUNK); + char *oggbuf = ogg_sync_buffer(&aspect->sync_state, ogg_bytes_to_read); + + if(0 == oggbuf) { + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR; + } + else { + size_t ogg_bytes_read = ogg_bytes_to_read; + + switch(read_callback(decoder, (FLAC__byte*)oggbuf, &ogg_bytes_read, client_data)) { + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK: + break; + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM: + aspect->end_of_stream = true; + break; + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; + default: + FLAC__ASSERT(0); + } + + if(ogg_sync_wrote(&aspect->sync_state, ogg_bytes_read) < 0) { + /* double protection; this will happen if the read callback returns more bytes than the max requested, which would overflow Ogg's internal buffer */ + FLAC__ASSERT(0); + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR; + } + } + } + else { /* ret < 0 */ + /* lost sync, bail out */ + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC; + } + } + } + + if (aspect->end_of_stream && *bytes == 0) { + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM; + } + + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK; +} diff --git a/deps/flac-1.3.2/src/libFLAC/ogg_encoder_aspect.c b/deps/flac-1.3.2/src/libFLAC/ogg_encoder_aspect.c new file mode 100644 index 0000000..ebd4614 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ogg_encoder_aspect.c @@ -0,0 +1,228 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> /* for memset() */ +#include "FLAC/assert.h" +#include "private/ogg_encoder_aspect.h" +#include "private/ogg_mapping.h" + +static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MAJOR = 1; +static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MINOR = 0; + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect) +{ + /* we will determine the serial number later if necessary */ + if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0) + return false; + + aspect->seen_magic = false; + aspect->is_first_packet = true; + aspect->samples_written = 0; + + return true; +} + +void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect) +{ + (void)ogg_stream_clear(&aspect->stream_state); + /*@@@ what about the page? */ +} + +void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value) +{ + aspect->serial_number = value; +} + +FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value) +{ + if(value < (1u << FLAC__OGG_MAPPING_NUM_HEADERS_LEN)) { + aspect->num_metadata = value; + return true; + } + else + return false; +} + +void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect) +{ + aspect->serial_number = 0; + aspect->num_metadata = 0; +} + +/* + * The basic FLAC -> Ogg mapping goes like this: + * + * - 'fLaC' magic and STREAMINFO block get combined into the first + * packet. The packet is prefixed with + * + the one-byte packet type 0x7F + * + 'FLAC' magic + * + the 2 byte Ogg FLAC mapping version number + * + tne 2 byte big-endian # of header packets + * - The first packet is flushed to the first page. + * - Each subsequent metadata block goes into its own packet. + * - Each metadata packet is flushed to page (this is not required, + * the mapping only requires that a flush must occur after all + * metadata is written). + * - Each subsequent FLAC audio frame goes into its own packet. + * + * WATCHOUT: + * This depends on the behavior of FLAC__StreamEncoder that we get a + * separate write callback for the fLaC magic, and then separate write + * callbacks for each metadata block and audio frame. + */ +FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data) +{ + /* WATCHOUT: + * This depends on the behavior of FLAC__StreamEncoder that 'samples' + * will be 0 for metadata writes. + */ + const FLAC__bool is_metadata = (samples == 0); + + /* + * Treat fLaC magic packet specially. We will note when we see it, then + * wait until we get the STREAMINFO and prepend it in that packet + */ + if(aspect->seen_magic) { + ogg_packet packet; + FLAC__byte synthetic_first_packet_body[ + FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + + FLAC__OGG_MAPPING_MAGIC_LENGTH + + FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + + FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + + FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + + FLAC__STREAM_SYNC_LENGTH + + FLAC__STREAM_METADATA_HEADER_LENGTH + + FLAC__STREAM_METADATA_STREAMINFO_LENGTH + ]; + + memset(&packet, 0, sizeof(packet)); + packet.granulepos = aspect->samples_written + samples; + + if(aspect->is_first_packet) { + FLAC__byte *b = synthetic_first_packet_body; + if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) { + /* + * If we get here, our assumption about the way write callbacks happen + * (explained above) is wrong + */ + FLAC__ASSERT(0); + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + } + /* add first header packet type */ + *b = FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; + b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH; + /* add 'FLAC' mapping magic */ + memcpy(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH); + b += FLAC__OGG_MAPPING_MAGIC_LENGTH; + /* add Ogg FLAC mapping major version number */ + memcpy(b, &FLAC__OGG_MAPPING_VERSION_MAJOR, FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH); + b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH; + /* add Ogg FLAC mapping minor version number */ + memcpy(b, &FLAC__OGG_MAPPING_VERSION_MINOR, FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH); + b += FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH; + /* add number of header packets */ + *b = (FLAC__byte)(aspect->num_metadata >> 8); + b++; + *b = (FLAC__byte)(aspect->num_metadata); + b++; + /* add native FLAC 'fLaC' magic */ + memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH); + b += FLAC__STREAM_SYNC_LENGTH; + /* add STREAMINFO */ + memcpy(b, buffer, bytes); + FLAC__ASSERT(b + bytes - synthetic_first_packet_body == sizeof(synthetic_first_packet_body)); + packet.packet = (unsigned char *)synthetic_first_packet_body; + packet.bytes = sizeof(synthetic_first_packet_body); + + packet.b_o_s = 1; + aspect->is_first_packet = false; + } + else { + packet.packet = (unsigned char *)buffer; + packet.bytes = bytes; + } + + if(is_last_block) { + /* we used to check: + * FLAC__ASSERT(total_samples_estimate == 0 || total_samples_estimate == aspect->samples_written + samples); + * but it's really not useful since total_samples_estimate is an estimate and can be inexact + */ + packet.e_o_s = 1; + } + + if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0) + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + + /*@@@ can't figure out a way to pass a useful number for 'samples' to the write_callback, so we'll just pass 0 */ + if(is_metadata) { + while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) { + if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + } + } + else { + while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) { + if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + } + } + } + else if(is_metadata && current_frame == 0 && samples == 0 && bytes == 4 && 0 == memcmp(buffer, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING))) { + aspect->seen_magic = true; + } + else { + /* + * If we get here, our assumption about the way write callbacks happen + * explained above is wrong + */ + FLAC__ASSERT(0); + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + } + + aspect->samples_written += samples; + + return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; +} diff --git a/deps/flac-1.3.2/src/libFLAC/ogg_helper.c b/deps/flac-1.3.2/src/libFLAC/ogg_helper.c new file mode 100644 index 0000000..7ca9160 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ogg_helper.c @@ -0,0 +1,210 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> /* for malloc() */ +#include <string.h> /* for memcmp(), memcpy() */ +#include "FLAC/assert.h" +#include "share/alloc.h" +#include "private/ogg_helper.h" +#include "protected/stream_encoder.h" + + +static FLAC__bool full_read_(FLAC__StreamEncoder *encoder, FLAC__byte *buffer, size_t bytes, FLAC__StreamEncoderReadCallback read_callback, void *client_data) +{ + while(bytes > 0) { + size_t bytes_read = bytes; + switch(read_callback(encoder, buffer, &bytes_read, client_data)) { + case FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE: + bytes -= bytes_read; + buffer += bytes_read; + break; + case FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM: + if(bytes_read == 0) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + return false; + } + bytes -= bytes_read; + buffer += bytes_read; + break; + case FLAC__STREAM_ENCODER_READ_STATUS_ABORT: + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + case FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED: + return false; + default: + /* double protection: */ + FLAC__ASSERT(0); + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } + } + + return true; +} + +void simple_ogg_page__init(ogg_page *page) +{ + page->header = 0; + page->header_len = 0; + page->body = 0; + page->body_len = 0; +} + +void simple_ogg_page__clear(ogg_page *page) +{ + if(page->header) + free(page->header); + if(page->body) + free(page->body); + simple_ogg_page__init(page); +} + +FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data) +{ + static const unsigned OGG_HEADER_FIXED_PORTION_LEN = 27; + static const unsigned OGG_MAX_HEADER_LEN = 27/*OGG_HEADER_FIXED_PORTION_LEN*/ + 255; + FLAC__byte crc[4]; + FLAC__StreamEncoderSeekStatus seek_status; + + FLAC__ASSERT(page->header == 0); + FLAC__ASSERT(page->header_len == 0); + FLAC__ASSERT(page->body == 0); + FLAC__ASSERT(page->body_len == 0); + + /* move the stream pointer to the supposed beginning of the page */ + if(0 == seek_callback) + return false; + if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { + if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } + + /* allocate space for the page header */ + if(0 == (page->header = safe_malloc_(OGG_MAX_HEADER_LEN))) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + /* read in the fixed part of the page header (up to but not including + * the segment table */ + if(!full_read_(encoder, page->header, OGG_HEADER_FIXED_PORTION_LEN, read_callback, client_data)) + return false; + + page->header_len = OGG_HEADER_FIXED_PORTION_LEN + page->header[26]; + + /* check to see if it's a correct, "simple" page (one packet only) */ + if( + memcmp(page->header, "OggS", 4) || /* doesn't start with OggS */ + (page->header[5] & 0x01) || /* continued packet */ + memcmp(page->header+6, "\0\0\0\0\0\0\0\0", 8) || /* granulepos is non-zero */ + page->header[26] == 0 /* packet is 0-size */ + ) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + return false; + } + + /* read in the segment table */ + if(!full_read_(encoder, page->header + OGG_HEADER_FIXED_PORTION_LEN, page->header[26], read_callback, client_data)) + return false; + + { + unsigned i; + + /* check to see that it specifies a single packet */ + for(i = 0; i < (unsigned)page->header[26] - 1; i++) { + if(page->header[i + OGG_HEADER_FIXED_PORTION_LEN] != 255) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + return false; + } + } + + page->body_len = 255 * i + page->header[i + OGG_HEADER_FIXED_PORTION_LEN]; + } + + /* allocate space for the page body */ + if(0 == (page->body = safe_malloc_(page->body_len))) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + /* read in the page body */ + if(!full_read_(encoder, page->body, page->body_len, read_callback, client_data)) + return false; + + /* check the CRC */ + memcpy(crc, page->header+22, 4); + ogg_page_checksum_set(page); + if(memcmp(crc, page->header+22, 4)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + return false; + } + + return true; +} + +FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data) +{ + FLAC__StreamEncoderSeekStatus seek_status; + + FLAC__ASSERT(page->header != 0); + FLAC__ASSERT(page->header_len != 0); + FLAC__ASSERT(page->body != 0); + FLAC__ASSERT(page->body_len != 0); + + /* move the stream pointer to the supposed beginning of the page */ + if(0 == seek_callback) + return false; + if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { + if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } + + ogg_page_checksum_set(page); + + /* re-write the page */ + if(write_callback((FLAC__StreamEncoder*)encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } + if(write_callback((FLAC__StreamEncoder*)encoder, page->body, page->body_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } + + return true; +} diff --git a/deps/flac-1.3.2/src/libFLAC/ogg_mapping.c b/deps/flac-1.3.2/src/libFLAC/ogg_mapping.c new file mode 100644 index 0000000..08fa514 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/ogg_mapping.c @@ -0,0 +1,48 @@ +/* libFLAC - Free Lossless Audio Codec + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/ogg_mapping.h" + +const unsigned FLAC__OGG_MAPPING_PACKET_TYPE_LEN = 8; /* bits */ + +const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE = 0x7f; + +const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC = (const FLAC__byte * const)"FLAC"; + +const unsigned FLAC__OGG_MAPPING_VERSION_MAJOR_LEN = 8; /* bits */ +const unsigned FLAC__OGG_MAPPING_VERSION_MINOR_LEN = 8; /* bits */ + +const unsigned FLAC__OGG_MAPPING_NUM_HEADERS_LEN = 16; /* bits */ diff --git a/deps/flac-1.3.2/src/libFLAC/stream_decoder.c b/deps/flac-1.3.2/src/libFLAC/stream_decoder.c new file mode 100644 index 0000000..7c8a26e --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/stream_decoder.c @@ -0,0 +1,3408 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> /* for malloc() */ +#include <string.h> /* for memset/memcpy() */ +#include <sys/stat.h> /* for stat() */ +#include <sys/types.h> /* for off_t */ +#include "share/compat.h" +#include "FLAC/assert.h" +#include "share/alloc.h" +#include "protected/stream_decoder.h" +#include "private/bitreader.h" +#include "private/bitmath.h" +#include "private/cpu.h" +#include "private/crc.h" +#include "private/fixed.h" +#include "private/format.h" +#include "private/lpc.h" +#include "private/md5.h" +#include "private/memory.h" +#include "private/macros.h" + + +/* technically this should be in an "export.c" but this is convenient enough */ +FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = FLAC__HAS_OGG; + + +/*********************************************************************** + * + * Private static data + * + ***********************************************************************/ + +static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; + +/*********************************************************************** + * + * Private class method prototypes + * + ***********************************************************************/ + +static void set_defaults_(FLAC__StreamDecoder *decoder); +static FILE *get_binary_stdin_(void); +static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels); +static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id); +static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); +static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); +static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); +static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); +static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length); +static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj); +static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj); +static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder); +static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder); +static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode); +static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder); +static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode); +static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode); +static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode); +static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode); +static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode); +static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended); +static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder); +static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data); +#if FLAC__HAS_OGG +static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes); +static FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); +#endif +static FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]); +static void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status); +static FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample); +#if FLAC__HAS_OGG +static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample); +#endif +static FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); +static FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); +static FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); +static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); +static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data); + +/*********************************************************************** + * + * Private class data + * + ***********************************************************************/ + +typedef struct FLAC__StreamDecoderPrivate { + FLAC__bool is_ogg; + FLAC__StreamDecoderReadCallback read_callback; + FLAC__StreamDecoderSeekCallback seek_callback; + FLAC__StreamDecoderTellCallback tell_callback; + FLAC__StreamDecoderLengthCallback length_callback; + FLAC__StreamDecoderEofCallback eof_callback; + FLAC__StreamDecoderWriteCallback write_callback; + FLAC__StreamDecoderMetadataCallback metadata_callback; + FLAC__StreamDecoderErrorCallback error_callback; + /* generic 32-bit datapath: */ + void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); + /* generic 64-bit datapath: */ + void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); + /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ + void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); + void *client_data; + FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ + FLAC__BitReader *input; + FLAC__int32 *output[FLAC__MAX_CHANNELS]; + FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ + FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; + unsigned output_capacity, output_channels; + FLAC__uint32 fixed_block_size, next_fixed_block_size; + FLAC__uint64 samples_decoded; + FLAC__bool has_stream_info, has_seek_table; + FLAC__StreamMetadata stream_info; + FLAC__StreamMetadata seek_table; + FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ + FLAC__byte *metadata_filter_ids; + size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ + FLAC__Frame frame; + FLAC__bool cached; /* true if there is a byte in lookahead */ + FLAC__CPUInfo cpuinfo; + FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */ + FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */ + /* unaligned (original) pointers to allocated data */ + FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS]; + FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */ + FLAC__bool internal_reset_hack; /* used only during init() so we can call reset to set up the decoder without rewinding the input */ + FLAC__bool is_seeking; + FLAC__MD5Context md5context; + FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */ + /* (the rest of these are only used for seeking) */ + FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */ + FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */ + FLAC__uint64 target_sample; + unsigned unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */ + FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */ +} FLAC__StreamDecoderPrivate; + +/*********************************************************************** + * + * Public static class data + * + ***********************************************************************/ + +FLAC_API const char * const FLAC__StreamDecoderStateString[] = { + "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", + "FLAC__STREAM_DECODER_READ_METADATA", + "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", + "FLAC__STREAM_DECODER_READ_FRAME", + "FLAC__STREAM_DECODER_END_OF_STREAM", + "FLAC__STREAM_DECODER_OGG_ERROR", + "FLAC__STREAM_DECODER_SEEK_ERROR", + "FLAC__STREAM_DECODER_ABORTED", + "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR", + "FLAC__STREAM_DECODER_UNINITIALIZED" +}; + +FLAC_API const char * const FLAC__StreamDecoderInitStatusString[] = { + "FLAC__STREAM_DECODER_INIT_STATUS_OK", + "FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER", + "FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS", + "FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR", + "FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE", + "FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED" +}; + +FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = { + "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", + "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM", + "FLAC__STREAM_DECODER_READ_STATUS_ABORT" +}; + +FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[] = { + "FLAC__STREAM_DECODER_SEEK_STATUS_OK", + "FLAC__STREAM_DECODER_SEEK_STATUS_ERROR", + "FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED" +}; + +FLAC_API const char * const FLAC__StreamDecoderTellStatusString[] = { + "FLAC__STREAM_DECODER_TELL_STATUS_OK", + "FLAC__STREAM_DECODER_TELL_STATUS_ERROR", + "FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED" +}; + +FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[] = { + "FLAC__STREAM_DECODER_LENGTH_STATUS_OK", + "FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR", + "FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED" +}; + +FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = { + "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", + "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT" +}; + +FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = { + "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", + "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", + "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH", + "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM" +}; + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ +FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) +{ + FLAC__StreamDecoder *decoder; + unsigned i; + + FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ + + decoder = calloc(1, sizeof(FLAC__StreamDecoder)); + if(decoder == 0) { + return 0; + } + + decoder->protected_ = calloc(1, sizeof(FLAC__StreamDecoderProtected)); + if(decoder->protected_ == 0) { + free(decoder); + return 0; + } + + decoder->private_ = calloc(1, sizeof(FLAC__StreamDecoderPrivate)); + if(decoder->private_ == 0) { + free(decoder->protected_); + free(decoder); + return 0; + } + + decoder->private_->input = FLAC__bitreader_new(); + if(decoder->private_->input == 0) { + free(decoder->private_); + free(decoder->protected_); + free(decoder); + return 0; + } + + decoder->private_->metadata_filter_ids_capacity = 16; + if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { + FLAC__bitreader_delete(decoder->private_->input); + free(decoder->private_); + free(decoder->protected_); + free(decoder); + return 0; + } + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + decoder->private_->output[i] = 0; + decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; + } + + decoder->private_->output_capacity = 0; + decoder->private_->output_channels = 0; + decoder->private_->has_seek_table = false; + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]); + + decoder->private_->file = 0; + + set_defaults_(decoder); + + decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; + + return decoder; +} + +FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) +{ + unsigned i; + + if (decoder == NULL) + return ; + + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->private_->input); + + (void)FLAC__stream_decoder_finish(decoder); + + if(0 != decoder->private_->metadata_filter_ids) + free(decoder->private_->metadata_filter_ids); + + FLAC__bitreader_delete(decoder->private_->input); + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]); + + free(decoder->private_); + free(decoder->protected_); + free(decoder); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +static FLAC__StreamDecoderInitStatus init_stream_internal_( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data, + FLAC__bool is_ogg +) +{ + FLAC__ASSERT(0 != decoder); + + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + + if(FLAC__HAS_OGG == 0 && is_ogg) + return FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER; + + if( + 0 == read_callback || + 0 == write_callback || + 0 == error_callback || + (seek_callback && (0 == tell_callback || 0 == length_callback || 0 == eof_callback)) + ) + return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + +#if FLAC__HAS_OGG + decoder->private_->is_ogg = is_ogg; + if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; +#endif + + /* + * get the CPU info and set the function pointers + */ + FLAC__cpu_info(&decoder->private_->cpuinfo); + /* first default to the non-asm routines */ + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; + /* now override with asm where appropriate */ +#ifndef FLAC__NO_ASM + if(decoder->private_->cpuinfo.use_asm) { +#ifdef FLAC__CPU_IA32 + FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); +#ifdef FLAC__HAS_NASM + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ + if(decoder->private_->cpuinfo.ia32.mmx) { + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; + } + else { + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; + } +#endif +#if FLAC__HAS_X86INTRIN && ! defined FLAC__INTEGER_ONLY_LIBRARY +# if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */ + if(decoder->private_->cpuinfo.ia32.sse2) { + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2; + } +# endif +# if defined FLAC__SSE4_1_SUPPORTED + if(decoder->private_->cpuinfo.ia32.sse41) { + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41; + } +# endif +#endif +#elif defined FLAC__CPU_X86_64 + FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); + /* No useful SSE optimizations yet */ +#endif + } +#endif + + /* from here on, errors are fatal */ + + if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; + } + + decoder->private_->read_callback = read_callback; + decoder->private_->seek_callback = seek_callback; + decoder->private_->tell_callback = tell_callback; + decoder->private_->length_callback = length_callback; + decoder->private_->eof_callback = eof_callback; + decoder->private_->write_callback = write_callback; + decoder->private_->metadata_callback = metadata_callback; + decoder->private_->error_callback = error_callback; + decoder->private_->client_data = client_data; + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; + decoder->private_->samples_decoded = 0; + decoder->private_->has_stream_info = false; + decoder->private_->cached = false; + + decoder->private_->do_md5_checking = decoder->protected_->md5_checking; + decoder->private_->is_seeking = false; + + decoder->private_->internal_reset_hack = true; /* so the following reset does not try to rewind the input */ + if(!FLAC__stream_decoder_reset(decoder)) { + /* above call sets the state for us */ + return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; + } + + return FLAC__STREAM_DECODER_INIT_STATUS_OK; +} + +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) +{ + return init_stream_internal_( + decoder, + read_callback, + seek_callback, + tell_callback, + length_callback, + eof_callback, + write_callback, + metadata_callback, + error_callback, + client_data, + /*is_ogg=*/false + ); +} + +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) +{ + return init_stream_internal_( + decoder, + read_callback, + seek_callback, + tell_callback, + length_callback, + eof_callback, + write_callback, + metadata_callback, + error_callback, + client_data, + /*is_ogg=*/true + ); +} + +static FLAC__StreamDecoderInitStatus init_FILE_internal_( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data, + FLAC__bool is_ogg +) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != file); + + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + + if(0 == write_callback || 0 == error_callback) + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + + /* + * To make sure that our file does not go unclosed after an error, we + * must assign the FILE pointer before any further error can occur in + * this routine. + */ + if(file == stdin) + file = get_binary_stdin_(); /* just to be safe */ + + decoder->private_->file = file; + + return init_stream_internal_( + decoder, + file_read_callback_, + decoder->private_->file == stdin? 0: file_seek_callback_, + decoder->private_->file == stdin? 0: file_tell_callback_, + decoder->private_->file == stdin? 0: file_length_callback_, + file_eof_callback_, + write_callback, + metadata_callback, + error_callback, + client_data, + is_ogg + ); +} + +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) +{ + return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false); +} + +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) +{ + return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); +} + +static FLAC__StreamDecoderInitStatus init_file_internal_( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data, + FLAC__bool is_ogg +) +{ + FILE *file; + + FLAC__ASSERT(0 != decoder); + + /* + * To make sure that our file does not go unclosed after an error, we + * have to do the same entrance checks here that are later performed + * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned. + */ + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + + if(0 == write_callback || 0 == error_callback) + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + + file = filename? flac_fopen(filename, "rb") : stdin; + + if(0 == file) + return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; + + return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, is_ogg); +} + +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) +{ + return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false); +} + +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) +{ + return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); +} + +FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) +{ + FLAC__bool md5_failed = false; + unsigned i; + + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + + if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) + return true; + + /* see the comment in FLAC__stream_decoder_reset() as to why we + * always call FLAC__MD5Final() + */ + FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); + + free(decoder->private_->seek_table.data.seek_table.points); + decoder->private_->seek_table.data.seek_table.points = 0; + decoder->private_->has_seek_table = false; + + FLAC__bitreader_free(decoder->private_->input); + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + /* WATCHOUT: + * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the + * output arrays have a buffer of up to 3 zeroes in front + * (at negative indices) for alignment purposes; we use 4 + * to keep the data well-aligned. + */ + if(0 != decoder->private_->output[i]) { + free(decoder->private_->output[i]-4); + decoder->private_->output[i] = 0; + } + if(0 != decoder->private_->residual_unaligned[i]) { + free(decoder->private_->residual_unaligned[i]); + decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; + } + } + decoder->private_->output_capacity = 0; + decoder->private_->output_channels = 0; + +#if FLAC__HAS_OGG + if(decoder->private_->is_ogg) + FLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect); +#endif + + if(0 != decoder->private_->file) { + if(decoder->private_->file != stdin) + fclose(decoder->private_->file); + decoder->private_->file = 0; + } + + if(decoder->private_->do_md5_checking) { + if(memcmp(decoder->private_->stream_info.data.stream_info.md5sum, decoder->private_->computed_md5sum, 16)) + md5_failed = true; + } + decoder->private_->is_seeking = false; + + set_defaults_(decoder); + + decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; + + return !md5_failed; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long value) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; +#if FLAC__HAS_OGG + /* can't check decoder->private_->is_ogg since that's not set until init time */ + FLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value); + return true; +#else + (void)value; + return false; +#endif +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + decoder->protected_->md5_checking = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE); + /* double protection */ + if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE) + return false; + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + decoder->private_->metadata_filter[type] = true; + if(type == FLAC__METADATA_TYPE_APPLICATION) + decoder->private_->metadata_filter_ids_count = 0; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT(0 != id); + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + + if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) + return true; + + FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); + + if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { + if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + decoder->private_->metadata_filter_ids_capacity *= 2; + } + + memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); + decoder->private_->metadata_filter_ids_count++; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder) +{ + unsigned i; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++) + decoder->private_->metadata_filter[i] = true; + decoder->private_->metadata_filter_ids_count = 0; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE); + /* double protection */ + if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE) + return false; + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + decoder->private_->metadata_filter[type] = false; + if(type == FLAC__METADATA_TYPE_APPLICATION) + decoder->private_->metadata_filter_ids_count = 0; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT(0 != id); + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + + if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) + return true; + + FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); + + if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { + if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + decoder->private_->metadata_filter_ids_capacity *= 2; + } + + memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); + decoder->private_->metadata_filter_ids_count++; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); + decoder->private_->metadata_filter_ids_count = 0; + return true; +} + +FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->state; +} + +FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder) +{ + return FLAC__StreamDecoderStateString[decoder->protected_->state]; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->md5_checking; +} + +FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->private_->has_stream_info? decoder->private_->stream_info.data.stream_info.total_samples : 0; +} + +FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->channels; +} + +FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->channel_assignment; +} + +FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->bits_per_sample; +} + +FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->sample_rate; +} + +FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->blocksize; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != position); + + if(FLAC__HAS_OGG && decoder->private_->is_ogg) + return false; + + if(0 == decoder->private_->tell_callback) + return false; + if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__STREAM_DECODER_TELL_STATUS_OK) + return false; + /* should never happen since all FLAC frames and metadata blocks are byte aligned, but check just in case */ + if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) + return false; + FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder)); + *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder); + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + + if(!decoder->private_->internal_reset_hack && decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) + return false; + + decoder->private_->samples_decoded = 0; + decoder->private_->do_md5_checking = false; + +#if FLAC__HAS_OGG + if(decoder->private_->is_ogg) + FLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect); +#endif + + if(!FLAC__bitreader_clear(decoder->private_->input)) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + + if(!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; + } + +#if FLAC__HAS_OGG + /*@@@ could go in !internal_reset_hack block below */ + if(decoder->private_->is_ogg) + FLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect); +#endif + + /* Rewind if necessary. If FLAC__stream_decoder_init() is calling us, + * (internal_reset_hack) don't try to rewind since we are already at + * the beginning of the stream and don't want to fail if the input is + * not seekable. + */ + if(!decoder->private_->internal_reset_hack) { + if(decoder->private_->file == stdin) + return false; /* can't rewind stdin, reset fails */ + if(decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR) + return false; /* seekable and seek fails, reset fails */ + } + else + decoder->private_->internal_reset_hack = false; + + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; + + decoder->private_->has_stream_info = false; + + free(decoder->private_->seek_table.data.seek_table.points); + decoder->private_->seek_table.data.seek_table.points = 0; + decoder->private_->has_seek_table = false; + + decoder->private_->do_md5_checking = decoder->protected_->md5_checking; + /* + * This goes in reset() and not flush() because according to the spec, a + * fixed-blocksize stream must stay that way through the whole stream. + */ + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; + + /* We initialize the FLAC__MD5Context even though we may never use it. This + * is because md5 checking may be turned on to start and then turned off if + * a seek occurs. So we init the context here and finalize it in + * FLAC__stream_decoder_finish() to make sure things are always cleaned up + * properly. + */ + FLAC__MD5Init(&decoder->private_->md5context); + + decoder->private_->first_frame_offset = 0; + decoder->private_->unparseable_frame_count = 0; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder) +{ + FLAC__bool got_a_frame; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while(1) { + switch(decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + if(!find_metadata_(decoder)) + return false; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_READ_METADATA: + if(!read_metadata_(decoder)) + return false; /* above function sets the status for us */ + else + return true; + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + if(!frame_sync_(decoder)) + return true; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_READ_FRAME: + if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/true)) + return false; /* above function sets the status for us */ + if(got_a_frame) + return true; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while(1) { + switch(decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + if(!find_metadata_(decoder)) + return false; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_READ_METADATA: + if(!read_metadata_(decoder)) + return false; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + case FLAC__STREAM_DECODER_READ_FRAME: + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder) +{ + FLAC__bool dummy; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while(1) { + switch(decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + if(!find_metadata_(decoder)) + return false; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_READ_METADATA: + if(!read_metadata_(decoder)) + return false; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + if(!frame_sync_(decoder)) + return true; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_READ_FRAME: + if(!read_frame_(decoder, &dummy, /*do_full_decode=*/true)) + return false; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder) +{ + FLAC__bool got_a_frame; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while(1) { + switch(decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + case FLAC__STREAM_DECODER_READ_METADATA: + return false; /* above function sets the status for us */ + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + if(!frame_sync_(decoder)) + return true; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_READ_FRAME: + if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false)) + return false; /* above function sets the status for us */ + if(got_a_frame) + return true; /* above function sets the status for us */ + break; + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample) +{ + FLAC__uint64 length; + + FLAC__ASSERT(0 != decoder); + + if( + decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && + decoder->protected_->state != FLAC__STREAM_DECODER_READ_METADATA && + decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && + decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME && + decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM + ) + return false; + + if(0 == decoder->private_->seek_callback) + return false; + + FLAC__ASSERT(decoder->private_->seek_callback); + FLAC__ASSERT(decoder->private_->tell_callback); + FLAC__ASSERT(decoder->private_->length_callback); + FLAC__ASSERT(decoder->private_->eof_callback); + + if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) + return false; + + decoder->private_->is_seeking = true; + + /* turn off md5 checking if a seek is attempted */ + decoder->private_->do_md5_checking = false; + + /* get the file length (currently our algorithm needs to know the length so it's also an error to get FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED) */ + if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__STREAM_DECODER_LENGTH_STATUS_OK) { + decoder->private_->is_seeking = false; + return false; + } + + /* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO, SEEK_TABLE, and first_frame_offset */ + if( + decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA || + decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA + ) { + if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) { + /* above call sets the state for us */ + decoder->private_->is_seeking = false; + return false; + } + /* check this again in case we didn't know total_samples the first time */ + if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) { + decoder->private_->is_seeking = false; + return false; + } + } + + { + const FLAC__bool ok = +#if FLAC__HAS_OGG + decoder->private_->is_ogg? + seek_to_absolute_sample_ogg_(decoder, length, sample) : +#endif + seek_to_absolute_sample_(decoder, length, sample) + ; + decoder->private_->is_seeking = false; + return ok; + } +} + +/*********************************************************************** + * + * Protected class methods + * + ***********************************************************************/ + +unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder) +{ + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + FLAC__ASSERT(!(FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) & 7)); + return FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) / 8; +} + +/*********************************************************************** + * + * Private class methods + * + ***********************************************************************/ + +void set_defaults_(FLAC__StreamDecoder *decoder) +{ + decoder->private_->is_ogg = false; + decoder->private_->read_callback = 0; + decoder->private_->seek_callback = 0; + decoder->private_->tell_callback = 0; + decoder->private_->length_callback = 0; + decoder->private_->eof_callback = 0; + decoder->private_->write_callback = 0; + decoder->private_->metadata_callback = 0; + decoder->private_->error_callback = 0; + decoder->private_->client_data = 0; + + memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); + decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true; + decoder->private_->metadata_filter_ids_count = 0; + + decoder->protected_->md5_checking = false; + +#if FLAC__HAS_OGG + FLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect); +#endif +} + +/* + * This will forcibly set stdin to binary mode (for OSes that require it) + */ +FILE *get_binary_stdin_(void) +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdin), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdin), _O_BINARY); +#elif defined __EMX__ + setmode(fileno(stdin), O_BINARY); +#endif + + return stdin; +} + +FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels) +{ + unsigned i; + FLAC__int32 *tmp; + + if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) + return true; + + /* simply using realloc() is not practical because the number of channels may change mid-stream */ + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + if(0 != decoder->private_->output[i]) { + free(decoder->private_->output[i]-4); + decoder->private_->output[i] = 0; + } + if(0 != decoder->private_->residual_unaligned[i]) { + free(decoder->private_->residual_unaligned[i]); + decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; + } + } + + for(i = 0; i < channels; i++) { + /* WATCHOUT: + * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the + * output arrays have a buffer of up to 3 zeroes in front + * (at negative indices) for alignment purposes; we use 4 + * to keep the data well-aligned. + */ + tmp = safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); + if(tmp == 0) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + memset(tmp, 0, sizeof(FLAC__int32)*4); + decoder->private_->output[i] = tmp + 4; + + if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + } + + decoder->private_->output_capacity = size; + decoder->private_->output_channels = channels; + + return true; +} + +FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) +{ + size_t i; + + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + + for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++) + if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))) + return true; + + return false; +} + +FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) +{ + FLAC__uint32 x; + unsigned i, id; + FLAC__bool first = true; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + for(i = id = 0; i < 4; ) { + if(decoder->private_->cached) { + x = (FLAC__uint32)decoder->private_->lookahead; + decoder->private_->cached = false; + } + else { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + } + if(x == FLAC__STREAM_SYNC_STRING[i]) { + first = true; + i++; + id = 0; + continue; + } + + if(id >= 3) + return false; + + if(x == ID3V2_TAG_[id]) { + id++; + i = 0; + if(id == 3) { + if(!skip_id3v2_tag_(decoder)) + return false; /* skip_id3v2_tag_ sets the state for us */ + } + continue; + } + id = 0; + if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->header_warmup[0] = (FLAC__byte)x; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + + /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ + /* else we have to check if the second byte is the end of a sync code */ + if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->lookahead = (FLAC__byte)x; + decoder->private_->cached = true; + } + else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ + decoder->private_->header_warmup[1] = (FLAC__byte)x; + decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; + return true; + } + } + i = 0; + if(first) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + first = false; + } + } + + decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA; + return true; +} + +FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) +{ + FLAC__bool is_last; + FLAC__uint32 i, x, type, length; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN)) + return false; /* read_callback_ sets the state for us */ + is_last = x? true : false; + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(type == FLAC__METADATA_TYPE_STREAMINFO) { + if(!read_metadata_streaminfo_(decoder, is_last, length)) + return false; + + decoder->private_->has_stream_info = true; + if(0 == memcmp(decoder->private_->stream_info.data.stream_info.md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) + decoder->private_->do_md5_checking = false; + if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] && decoder->private_->metadata_callback) + decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data); + } + else if(type == FLAC__METADATA_TYPE_SEEKTABLE) { + /* just in case we already have a seek table, and reading the next one fails: */ + decoder->private_->has_seek_table = false; + + if(!read_metadata_seektable_(decoder, is_last, length)) + return false; + + decoder->private_->has_seek_table = true; + if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback) + decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); + } + else { + FLAC__bool skip_it = !decoder->private_->metadata_filter[type]; + unsigned real_length = length; + FLAC__StreamMetadata block; + + memset(&block, 0, sizeof(block)); + block.is_last = is_last; + block.type = (FLAC__MetadataType)type; + block.length = length; + + if(type == FLAC__METADATA_TYPE_APPLICATION) { + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)) + return false; /* read_callback_ sets the state for us */ + + if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */ + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/ + return false; + } + + real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8; + + if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) + skip_it = !skip_it; + } + + if(skip_it) { + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) + return false; /* read_callback_ sets the state for us */ + } + else { + FLAC__bool ok = true; + switch(type) { + case FLAC__METADATA_TYPE_PADDING: + /* skip the padding bytes */ + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) + ok = false; /* read_callback_ sets the state for us */ + break; + case FLAC__METADATA_TYPE_APPLICATION: + /* remember, we read the ID already */ + if(real_length > 0) { + if(0 == (block.data.application.data = malloc(real_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + ok = false; + } + else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) + ok = false; /* read_callback_ sets the state for us */ + } + else + block.data.application.data = 0; + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length)) + ok = false; + break; + case FLAC__METADATA_TYPE_CUESHEET: + if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) + ok = false; + break; + case FLAC__METADATA_TYPE_PICTURE: + if(!read_metadata_picture_(decoder, &block.data.picture)) + ok = false; + break; + case FLAC__METADATA_TYPE_STREAMINFO: + case FLAC__METADATA_TYPE_SEEKTABLE: + FLAC__ASSERT(0); + break; + default: + if(real_length > 0) { + if(0 == (block.data.unknown.data = malloc(real_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + ok = false; + } + else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) + ok = false; /* read_callback_ sets the state for us */ + } + else + block.data.unknown.data = 0; + break; + } + if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback) + decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); + + /* now we have to free any malloc()ed data in the block */ + switch(type) { + case FLAC__METADATA_TYPE_PADDING: + break; + case FLAC__METADATA_TYPE_APPLICATION: + if(0 != block.data.application.data) + free(block.data.application.data); + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if(0 != block.data.vorbis_comment.vendor_string.entry) + free(block.data.vorbis_comment.vendor_string.entry); + if(block.data.vorbis_comment.num_comments > 0) + for(i = 0; i < block.data.vorbis_comment.num_comments; i++) + if(0 != block.data.vorbis_comment.comments[i].entry) + free(block.data.vorbis_comment.comments[i].entry); + if(0 != block.data.vorbis_comment.comments) + free(block.data.vorbis_comment.comments); + break; + case FLAC__METADATA_TYPE_CUESHEET: + if(block.data.cue_sheet.num_tracks > 0) + for(i = 0; i < block.data.cue_sheet.num_tracks; i++) + if(0 != block.data.cue_sheet.tracks[i].indices) + free(block.data.cue_sheet.tracks[i].indices); + if(0 != block.data.cue_sheet.tracks) + free(block.data.cue_sheet.tracks); + break; + case FLAC__METADATA_TYPE_PICTURE: + if(0 != block.data.picture.mime_type) + free(block.data.picture.mime_type); + if(0 != block.data.picture.description) + free(block.data.picture.description); + if(0 != block.data.picture.data) + free(block.data.picture.data); + break; + case FLAC__METADATA_TYPE_STREAMINFO: + case FLAC__METADATA_TYPE_SEEKTABLE: + FLAC__ASSERT(0); + default: + if(0 != block.data.unknown.data) + free(block.data.unknown.data); + break; + } + + if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */ + return false; + } + } + + if(is_last) { + /* if this fails, it's OK, it's just a hint for the seek routine */ + if(!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->first_frame_offset)) + decoder->private_->first_frame_offset = 0; + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + } + + return true; +} + +FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length) +{ + FLAC__uint32 x; + unsigned bits, used_bits = 0; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + decoder->private_->stream_info.type = FLAC__METADATA_TYPE_STREAMINFO; + decoder->private_->stream_info.is_last = is_last; + decoder->private_->stream_info.length = length; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, bits)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.min_blocksize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.max_blocksize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.min_framesize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.max_framesize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.sample_rate = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.channels = x+1; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) + return false; /* read_callback_ sets the state for us */ + used_bits += bits; + + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16)) + return false; /* read_callback_ sets the state for us */ + used_bits += 16*8; + + /* skip the rest of the block */ + FLAC__ASSERT(used_bits % 8 == 0); + length -= (used_bits / 8); + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) + return false; /* read_callback_ sets the state for us */ + + return true; +} + +FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length) +{ + FLAC__uint32 i, x; + FLAC__uint64 xx; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + decoder->private_->seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE; + decoder->private_->seek_table.is_last = is_last; + decoder->private_->seek_table.length = length; + + decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + + /* use realloc since we may pass through here several times (e.g. after seeking) */ + if(0 == (decoder->private_->seek_table.data.seek_table.points = safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) { + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx; + + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx; + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x; + } + length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH); + /* if there is a partial point left, skip over it */ + if(length > 0) { + /*@@@ do a send_error_to_client_() here? there's an argument for either way */ + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) + return false; /* read_callback_ sets the state for us */ + } + + return true; +} + +FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length) +{ + FLAC__uint32 i; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + /* read vendor string */ + if (length >= 8) { + length -= 8; /* vendor string length + num comments entries alone take 8 bytes */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) + return false; /* read_callback_ sets the state for us */ + if (obj->vendor_string.length > 0) { + if (length < obj->vendor_string.length) { + obj->vendor_string.length = 0; + obj->vendor_string.entry = 0; + goto skip; + } + else + length -= obj->vendor_string.length; + if (0 == (obj->vendor_string.entry = safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) + return false; /* read_callback_ sets the state for us */ + obj->vendor_string.entry[obj->vendor_string.length] = '\0'; + } + else + obj->vendor_string.entry = 0; + + /* read num comments */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) + return false; /* read_callback_ sets the state for us */ + + /* read comments */ + if (obj->num_comments > 100000) { + /* Possibly malicious file. */ + obj->num_comments = 0; + return false; + } + if (obj->num_comments > 0) { + if (0 == (obj->comments = safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { + obj->num_comments = 0; + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for (i = 0; i < obj->num_comments; i++) { + /* Initialize here just to make sure. */ + obj->comments[i].length = 0; + obj->comments[i].entry = 0; + + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (length < 4) { + obj->num_comments = i; + goto skip; + } + else + length -= 4; + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) { + obj->num_comments = i; + return false; /* read_callback_ sets the state for us */ + } + if (obj->comments[i].length > 0) { + if (length < obj->comments[i].length) { + obj->num_comments = i; + goto skip; + } + else + length -= obj->comments[i].length; + if (0 == (obj->comments[i].entry = safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + obj->num_comments = i; + return false; + } + memset (obj->comments[i].entry, 0, obj->comments[i].length) ; + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) { + obj->num_comments = i; + goto skip; + } + obj->comments[i].entry[obj->comments[i].length] = '\0'; + } + else + obj->comments[i].entry = 0; + } + } + } + + skip: + if (length > 0) { + /* length > 0 can only happen on files with invalid data in comments */ + if(obj->num_comments < 1) { + free(obj->comments); + obj->comments = NULL; + } + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) + return false; /* read_callback_ sets the state for us */ + } + + return true; +} + +FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj) +{ + FLAC__uint32 i, j, x; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + memset(obj, 0, sizeof(FLAC__StreamMetadata_CueSheet)); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &obj->lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) + return false; /* read_callback_ sets the state for us */ + obj->is_cd = x? true : false; + + if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) + return false; /* read_callback_ sets the state for us */ + obj->num_tracks = x; + + if(obj->num_tracks > 0) { + if(0 == (obj->tracks = safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for(i = 0; i < obj->num_tracks; i++) { + FLAC__StreamMetadata_CueSheet_Track *track = &obj->tracks[i]; + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) + return false; /* read_callback_ sets the state for us */ + track->number = (FLAC__byte)x; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) + return false; /* read_callback_ sets the state for us */ + track->type = x; + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) + return false; /* read_callback_ sets the state for us */ + track->pre_emphasis = x; + + if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) + return false; /* read_callback_ sets the state for us */ + track->num_indices = (FLAC__byte)x; + + if(track->num_indices > 0) { + if(0 == (track->indices = safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for(j = 0; j < track->num_indices; j++) { + FLAC__StreamMetadata_CueSheet_Index *indx = &track->indices[j]; + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) + return false; /* read_callback_ sets the state for us */ + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) + return false; /* read_callback_ sets the state for us */ + indx->number = (FLAC__byte)x; + + if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) + return false; /* read_callback_ sets the state for us */ + } + } + } + } + + return true; +} + +FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj) +{ + FLAC__uint32 x; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + /* read type */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) + return false; /* read_callback_ sets the state for us */ + obj->type = x; + + /* read MIME type */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) + return false; /* read_callback_ sets the state for us */ + if(0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if(x > 0) { + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->mime_type, x)) + return false; /* read_callback_ sets the state for us */ + } + obj->mime_type[x] = '\0'; + + /* read description */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) + return false; /* read_callback_ sets the state for us */ + if(0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if(x > 0) { + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->description, x)) + return false; /* read_callback_ sets the state for us */ + } + obj->description[x] = '\0'; + + /* read width */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN)) + return false; /* read_callback_ sets the state for us */ + + /* read height */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN)) + return false; /* read_callback_ sets the state for us */ + + /* read depth */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN)) + return false; /* read_callback_ sets the state for us */ + + /* read colors */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN)) + return false; /* read_callback_ sets the state for us */ + + /* read data */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) + return false; /* read_callback_ sets the state for us */ + if(0 == (obj->data = safe_malloc_(obj->data_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if(obj->data_length > 0) { + if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->data, obj->data_length)) + return false; /* read_callback_ sets the state for us */ + } + + return true; +} + +FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder) +{ + FLAC__uint32 x; + unsigned i, skip; + + /* skip the version and flags bytes */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 24)) + return false; /* read_callback_ sets the state for us */ + /* get the size (in bytes) to skip */ + skip = 0; + for(i = 0; i < 4; i++) { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + skip <<= 7; + skip |= (x & 0x7f); + } + /* skip the rest of the tag */ + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, skip)) + return false; /* read_callback_ sets the state for us */ + return true; +} + +FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) +{ + FLAC__uint32 x; + FLAC__bool first = true; + + /* If we know the total number of samples in the stream, stop if we've read that many. */ + /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */ + if(FLAC__stream_decoder_get_total_samples(decoder) > 0) { + if(decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) { + decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; + return true; + } + } + + /* make sure we're byte aligned */ + if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) + return false; /* read_callback_ sets the state for us */ + } + + while(1) { + if(decoder->private_->cached) { + x = (FLAC__uint32)decoder->private_->lookahead; + decoder->private_->cached = false; + } + else { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + } + if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->header_warmup[0] = (FLAC__byte)x; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + + /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ + /* else we have to check if the second byte is the end of a sync code */ + if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->lookahead = (FLAC__byte)x; + decoder->private_->cached = true; + } + else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ + decoder->private_->header_warmup[1] = (FLAC__byte)x; + decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; + return true; + } + } + if(first) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + first = false; + } + } + + return true; +} + +FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode) +{ + unsigned channel; + unsigned i; + FLAC__int32 mid, side; + unsigned frame_crc; /* the one we calculate from the input stream */ + FLAC__uint32 x; + + *got_a_frame = false; + + /* init the CRC */ + frame_crc = 0; + frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc); + frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc); + FLAC__bitreader_reset_read_crc16(decoder->private_->input, (FLAC__uint16)frame_crc); + + if(!read_frame_header_(decoder)) + return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */ + return true; + if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels)) + return false; + for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { + /* + * first figure the correct bits-per-sample of the subframe + */ + unsigned bps = decoder->private_->frame.header.bits_per_sample; + switch(decoder->private_->frame.header.channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + /* no adjustment needed */ + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + if(channel == 1) + bps++; + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + if(channel == 0) + bps++; + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + if(channel == 1) + bps++; + break; + default: + FLAC__ASSERT(0); + } + /* + * now read it + */ + if(!read_subframe_(decoder, channel, bps, do_full_decode)) + return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ + return true; + } + if(!read_zero_padding_(decoder)) + return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */ + return true; + + /* + * Read the frame CRC-16 from the footer and check + */ + frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input); + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN)) + return false; /* read_callback_ sets the state for us */ + if(frame_crc == x) { + if(do_full_decode) { + /* Undo any special channel coding */ + switch(decoder->private_->frame.header.channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + /* do nothing */ + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + decoder->private_->output[0][i] += decoder->private_->output[1][i]; + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { +#if 1 + mid = decoder->private_->output[0][i]; + side = decoder->private_->output[1][i]; + mid = ((uint32_t) mid) << 1; + mid |= (side & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + side) >> 1; + decoder->private_->output[1][i] = (mid - side) >> 1; +#else + /* OPT: without 'side' temp variable */ + mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; + decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; +#endif + } + break; + default: + FLAC__ASSERT(0); + break; + } + } + } + else { + /* Bad frame, emit error and zero the output signal */ + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH); + if(do_full_decode) { + for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { + memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + } + } + } + + *got_a_frame = true; + + /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */ + if(decoder->private_->next_fixed_block_size) + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size; + + /* put the latest values into the public section of the decoder instance */ + decoder->protected_->channels = decoder->private_->frame.header.channels; + decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment; + decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample; + decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate; + decoder->protected_->blocksize = decoder->private_->frame.header.blocksize; + + FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; + + /* write it */ + if(do_full_decode) { + if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } + } + + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; +} + +FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) +{ + FLAC__uint32 x; + FLAC__uint64 xx; + unsigned i, blocksize_hint = 0, sample_rate_hint = 0; + FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */ + unsigned raw_header_len; + FLAC__bool is_unparseable = false; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + /* init the raw header with the saved bits from synchronization */ + raw_header[0] = decoder->private_->header_warmup[0]; + raw_header[1] = decoder->private_->header_warmup[1]; + raw_header_len = 2; + + /* check to make sure that reserved bit is 0 */ + if(raw_header[1] & 0x02) /* MAGIC NUMBER */ + is_unparseable = true; + + /* + * Note that along the way as we read the header, we look for a sync + * code inside. If we find one it would indicate that our original + * sync was bad since there cannot be a sync code in a valid header. + * + * Three kinds of things can go wrong when reading the frame header: + * 1) We may have sync'ed incorrectly and not landed on a frame header. + * If we don't find a sync code, it can end up looking like we read + * a valid but unparseable header, until getting to the frame header + * CRC. Even then we could get a false positive on the CRC. + * 2) We may have sync'ed correctly but on an unparseable frame (from a + * future encoder). + * 3) We may be on a damaged frame which appears valid but unparseable. + * + * For all these reasons, we try and read a complete frame header as + * long as it seems valid, even if unparseable, up until the frame + * header CRC. + */ + + /* + * read in the raw header as bytes so we can CRC it, and parse it on the way + */ + for(i = 0; i < 2; i++) { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */ + decoder->private_->lookahead = (FLAC__byte)x; + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + raw_header[raw_header_len++] = (FLAC__byte)x; + } + + switch(x = raw_header[2] >> 4) { + case 0: + is_unparseable = true; + break; + case 1: + decoder->private_->frame.header.blocksize = 192; + break; + case 2: + case 3: + case 4: + case 5: + decoder->private_->frame.header.blocksize = 576 << (x-2); + break; + case 6: + case 7: + blocksize_hint = x; + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + decoder->private_->frame.header.blocksize = 256 << (x-8); + break; + default: + FLAC__ASSERT(0); + break; + } + + switch(x = raw_header[2] & 0x0f) { + case 0: + if(decoder->private_->has_stream_info) + decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate; + else + is_unparseable = true; + break; + case 1: + decoder->private_->frame.header.sample_rate = 88200; + break; + case 2: + decoder->private_->frame.header.sample_rate = 176400; + break; + case 3: + decoder->private_->frame.header.sample_rate = 192000; + break; + case 4: + decoder->private_->frame.header.sample_rate = 8000; + break; + case 5: + decoder->private_->frame.header.sample_rate = 16000; + break; + case 6: + decoder->private_->frame.header.sample_rate = 22050; + break; + case 7: + decoder->private_->frame.header.sample_rate = 24000; + break; + case 8: + decoder->private_->frame.header.sample_rate = 32000; + break; + case 9: + decoder->private_->frame.header.sample_rate = 44100; + break; + case 10: + decoder->private_->frame.header.sample_rate = 48000; + break; + case 11: + decoder->private_->frame.header.sample_rate = 96000; + break; + case 12: + case 13: + case 14: + sample_rate_hint = x; + break; + case 15: + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + default: + FLAC__ASSERT(0); + } + + x = (unsigned)(raw_header[3] >> 4); + if(x & 8) { + decoder->private_->frame.header.channels = 2; + switch(x & 7) { + case 0: + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE; + break; + case 1: + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE; + break; + case 2: + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE; + break; + default: + is_unparseable = true; + break; + } + } + else { + decoder->private_->frame.header.channels = (unsigned)x + 1; + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; + } + + switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) { + case 0: + if(decoder->private_->has_stream_info) + decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample; + else + is_unparseable = true; + break; + case 1: + decoder->private_->frame.header.bits_per_sample = 8; + break; + case 2: + decoder->private_->frame.header.bits_per_sample = 12; + break; + case 4: + decoder->private_->frame.header.bits_per_sample = 16; + break; + case 5: + decoder->private_->frame.header.bits_per_sample = 20; + break; + case 6: + decoder->private_->frame.header.bits_per_sample = 24; + break; + case 3: + case 7: + is_unparseable = true; + break; + default: + FLAC__ASSERT(0); + break; + } + + /* check to make sure that reserved bit is 0 */ + if(raw_header[3] & 0x01) /* MAGIC NUMBER */ + is_unparseable = true; + + /* read the frame's starting sample number (or frame number as the case may be) */ + if( + raw_header[1] & 0x01 || + /*@@@ this clause is a concession to the old way of doing variable blocksize; the only known implementation is flake and can probably be removed without inconveniencing anyone */ + (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize) + ) { /* variable blocksize */ + if(!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len)) + return false; /* read_callback_ sets the state for us */ + if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */ + decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; + decoder->private_->frame.header.number.sample_number = xx; + } + else { /* fixed blocksize */ + if(!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len)) + return false; /* read_callback_ sets the state for us */ + if(x == 0xffffffff) { /* i.e. non-UTF8 code... */ + decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER; + decoder->private_->frame.header.number.frame_number = x; + } + + if(blocksize_hint) { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + raw_header[raw_header_len++] = (FLAC__byte)x; + if(blocksize_hint == 7) { + FLAC__uint32 _x; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8)) + return false; /* read_callback_ sets the state for us */ + raw_header[raw_header_len++] = (FLAC__byte)_x; + x = (x << 8) | _x; + } + decoder->private_->frame.header.blocksize = x+1; + } + + if(sample_rate_hint) { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + raw_header[raw_header_len++] = (FLAC__byte)x; + if(sample_rate_hint != 12) { + FLAC__uint32 _x; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8)) + return false; /* read_callback_ sets the state for us */ + raw_header[raw_header_len++] = (FLAC__byte)_x; + x = (x << 8) | _x; + } + if(sample_rate_hint == 12) + decoder->private_->frame.header.sample_rate = x*1000; + else if(sample_rate_hint == 13) + decoder->private_->frame.header.sample_rate = x; + else + decoder->private_->frame.header.sample_rate = x*10; + } + + /* read the CRC-8 byte */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) + return false; /* read_callback_ sets the state for us */ + crc8 = (FLAC__byte)x; + + if(FLAC__crc8(raw_header, raw_header_len) != crc8) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + /* calculate the sample number from the frame number if needed */ + decoder->private_->next_fixed_block_size = 0; + if(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { + x = decoder->private_->frame.header.number.frame_number; + decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; + if(decoder->private_->fixed_block_size) + decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->fixed_block_size * (FLAC__uint64)x; + else if(decoder->private_->has_stream_info) { + if(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize) { + decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x; + decoder->private_->next_fixed_block_size = decoder->private_->stream_info.data.stream_info.max_blocksize; + } + else + is_unparseable = true; + } + else if(x == 0) { + decoder->private_->frame.header.number.sample_number = 0; + decoder->private_->next_fixed_block_size = decoder->private_->frame.header.blocksize; + } + else { + /* can only get here if the stream has invalid frame numbering and no STREAMINFO, so assume it's not the last (possibly short) frame */ + decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x; + } + } + + if(is_unparseable) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + return true; +} + +FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode) +{ + FLAC__uint32 x; + FLAC__bool wasted_bits; + unsigned i; + + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) /* MAGIC NUMBER */ + return false; /* read_callback_ sets the state for us */ + + wasted_bits = (x & 1); + x &= 0xfe; + + if(wasted_bits) { + unsigned u; + if(!FLAC__bitreader_read_unary_unsigned(decoder->private_->input, &u)) + return false; /* read_callback_ sets the state for us */ + decoder->private_->frame.subframes[channel].wasted_bits = u+1; + if (decoder->private_->frame.subframes[channel].wasted_bits >= bps) + return false; + bps -= decoder->private_->frame.subframes[channel].wasted_bits; + } + else + decoder->private_->frame.subframes[channel].wasted_bits = 0; + + /* + * Lots of magic numbers here + */ + if(x & 0x80) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + else if(x == 0) { + if(!read_subframe_constant_(decoder, channel, bps, do_full_decode)) + return false; + } + else if(x == 2) { + if(!read_subframe_verbatim_(decoder, channel, bps, do_full_decode)) + return false; + } + else if(x < 16) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + else if(x <= 24) { + if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7, do_full_decode)) + return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ + return true; + } + else if(x < 64) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + else { + if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1, do_full_decode)) + return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ + return true; + } + + if(wasted_bits && do_full_decode) { + x = decoder->private_->frame.subframes[channel].wasted_bits; + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + uint32_t val = decoder->private_->output[channel][i]; + decoder->private_->output[channel][i] = (val << x); + } + } + + return true; +} + +FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode) +{ + FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant; + FLAC__int32 x; + unsigned i; + FLAC__int32 *output = decoder->private_->output[channel]; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; + + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) + return false; /* read_callback_ sets the state for us */ + + subframe->value = x; + + /* decode the subframe */ + if(do_full_decode) { + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + output[i] = x; + } + + return true; +} + +FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode) +{ + FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed; + FLAC__int32 i32; + FLAC__uint32 u32; + unsigned u; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED; + + subframe->residual = decoder->private_->residual[channel]; + subframe->order = order; + + /* read warm-up samples */ + for(u = 0; u < order; u++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) + return false; /* read_callback_ sets the state for us */ + subframe->warmup[u] = i32; + } + + /* read entropy coding method info */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) + return false; /* read_callback_ sets the state for us */ + subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; + switch(subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) + return false; /* read_callback_ sets the state for us */ + if(decoder->private_->frame.header.blocksize >> u32 < order) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->entropy_coding_method.data.partitioned_rice.order = u32; + subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; + break; + default: + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + /* read residual */ + switch(subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2)) + return false; + break; + default: + FLAC__ASSERT(0); + } + + /* decode the subframe */ + if(do_full_decode) { + memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); + FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + } + + return true; +} + +FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode) +{ + FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc; + FLAC__int32 i32; + FLAC__uint32 u32; + unsigned u; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC; + + subframe->residual = decoder->private_->residual[channel]; + subframe->order = order; + + /* read warm-up samples */ + for(u = 0; u < order; u++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) + return false; /* read_callback_ sets the state for us */ + subframe->warmup[u] = i32; + } + + /* read qlp coeff precision */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) + return false; /* read_callback_ sets the state for us */ + if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->qlp_coeff_precision = u32+1; + + /* read qlp shift */ + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) + return false; /* read_callback_ sets the state for us */ + if(i32 < 0) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->quantization_level = i32; + + /* read quantized lp coefficiencts */ + for(u = 0; u < order; u++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision)) + return false; /* read_callback_ sets the state for us */ + subframe->qlp_coeff[u] = i32; + } + + /* read entropy coding method info */ + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) + return false; /* read_callback_ sets the state for us */ + subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; + switch(subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) + return false; /* read_callback_ sets the state for us */ + if(decoder->private_->frame.header.blocksize >> u32 < order) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->entropy_coding_method.data.partitioned_rice.order = u32; + subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; + break; + default: + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + /* read residual */ + switch(subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2)) + return false; + break; + default: + FLAC__ASSERT(0); + } + + /* decode the subframe */ + if(do_full_decode) { + memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); + if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) + if(bps <= 16 && subframe->qlp_coeff_precision <= 16) + decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + else + decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + else + decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + } + + return true; +} + +FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode) +{ + FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim; + FLAC__int32 x, *residual = decoder->private_->residual[channel]; + unsigned i; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; + + subframe->data = residual; + + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) + return false; /* read_callback_ sets the state for us */ + residual[i] = x; + } + + /* decode the subframe */ + if(do_full_decode) + memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + + return true; +} + +FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended) +{ + FLAC__uint32 rice_parameter; + int i; + unsigned partition, sample, u; + const unsigned partitions = 1u << partition_order; + const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order; + const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; + const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + + /* invalid predictor and partition orders mush be handled in the callers */ + FLAC__ASSERT(partition_order > 0? partition_samples >= predictor_order : decoder->private_->frame.header.blocksize >= predictor_order); + + if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + sample = 0; + for(partition = 0; partition < partitions; partition++) { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, plen)) + return false; /* read_callback_ sets the state for us */ + partitioned_rice_contents->parameters[partition] = rice_parameter; + if(rice_parameter < pesc) { + partitioned_rice_contents->raw_bits[partition] = 0; + u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; + if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) + return false; /* read_callback_ sets the state for us */ + sample += u; + } + else { + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) + return false; /* read_callback_ sets the state for us */ + partitioned_rice_contents->raw_bits[partition] = rice_parameter; + for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter)) + return false; /* read_callback_ sets the state for us */ + residual[sample] = i; + } + } + } + + return true; +} + +FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder) +{ + if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { + FLAC__uint32 zero = 0; + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) + return false; /* read_callback_ sets the state for us */ + if(zero != 0) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + } + } + return true; +} + +FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data) +{ + FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data; + + if( +#if FLAC__HAS_OGG + /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */ + !decoder->private_->is_ogg && +#endif + decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data) + ) { + *bytes = 0; + decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; + return false; + } + else if(*bytes > 0) { + /* While seeking, it is possible for our seek to land in the + * middle of audio data that looks exactly like a frame header + * from a future version of an encoder. When that happens, our + * error callback will get an + * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its + * unparseable_frame_count. But there is a remote possibility + * that it is properly synced at such a "future-codec frame", + * so to make sure, we wait to see many "unparseable" errors in + * a row before bailing out. + */ + if(decoder->private_->is_seeking && decoder->private_->unparseable_frame_count > 20) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } + else { + const FLAC__StreamDecoderReadStatus status = +#if FLAC__HAS_OGG + decoder->private_->is_ogg? + read_callback_ogg_aspect_(decoder, buffer, bytes) : +#endif + decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data) + ; + if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } + else if(*bytes == 0) { + if( + status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM || + ( +#if FLAC__HAS_OGG + /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */ + !decoder->private_->is_ogg && +#endif + decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data) + ) + ) { + decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; + return false; + } + else + return true; + } + else + return true; + } + } + else { + /* abort to avoid a deadlock */ + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } + /* [1] @@@ HACK NOTE: The end-of-stream checking has to be hacked around + * for Ogg FLAC. This is because the ogg decoder aspect can lose sync + * and at the same time hit the end of the stream (for example, seeking + * to a point that is after the beginning of the last Ogg page). There + * is no way to report an Ogg sync loss through the callbacks (see note + * in read_callback_ogg_aspect_()) so it returns CONTINUE with *bytes==0. + * So to keep the decoder from stopping at this point we gate the call + * to the eof_callback and let the Ogg decoder aspect set the + * end-of-stream state when it is needed. + */ +} + +#if FLAC__HAS_OGG +FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes) +{ + switch(FLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) { + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK: + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + /* we don't really have a way to handle lost sync via read + * callback so we'll let it pass and let the underlying + * FLAC decoder catch the error + */ + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC: + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM: + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR: + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + default: + FLAC__ASSERT(0); + /* double protection */ + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + } +} + +FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) +{ + FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)void_decoder; + + switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) { + case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK; + case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM; + case FLAC__STREAM_DECODER_READ_STATUS_ABORT: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; + default: + /* double protection: */ + FLAC__ASSERT(0); + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; + } +} +#endif + +FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]) +{ + if(decoder->private_->is_seeking) { + FLAC__uint64 this_frame_sample = frame->header.number.sample_number; + FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize; + FLAC__uint64 target_sample = decoder->private_->target_sample; + + FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + +#if FLAC__HAS_OGG + decoder->private_->got_a_frame = true; +#endif + decoder->private_->last_frame = *frame; /* save the frame */ + if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */ + unsigned delta = (unsigned)(target_sample - this_frame_sample); + /* kick out of seek mode */ + decoder->private_->is_seeking = false; + /* shift out the samples before target_sample */ + if(delta > 0) { + unsigned channel; + const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS]; + for(channel = 0; channel < frame->header.channels; channel++) + newbuffer[channel] = buffer[channel] + delta; + decoder->private_->last_frame.header.blocksize -= delta; + decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta; + /* write the relevant samples */ + return decoder->private_->write_callback(decoder, &decoder->private_->last_frame, newbuffer, decoder->private_->client_data); + } + else { + /* write the relevant samples */ + return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); + } + } + else { + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; + } + } + else { + /* + * If we never got STREAMINFO, turn off MD5 checking to save + * cycles since we don't have a sum to compare to anyway + */ + if(!decoder->private_->has_stream_info) + decoder->private_->do_md5_checking = false; + if(decoder->private_->do_md5_checking) { + if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); + } +} + +void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) +{ + if(!decoder->private_->is_seeking) + decoder->private_->error_callback(decoder, status, decoder->private_->client_data); + else if(status == FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM) + decoder->private_->unparseable_frame_count++; +} + +FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) +{ + FLAC__uint64 first_frame_offset = decoder->private_->first_frame_offset, lower_bound, upper_bound, lower_bound_sample, upper_bound_sample, this_frame_sample; + FLAC__int64 pos = -1; + int i; + unsigned approx_bytes_per_frame; + FLAC__bool first_seek = true; + const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder); + const unsigned min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize; + const unsigned max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize; + const unsigned max_framesize = decoder->private_->stream_info.data.stream_info.max_framesize; + const unsigned min_framesize = decoder->private_->stream_info.data.stream_info.min_framesize; + /* take these from the current frame in case they've changed mid-stream */ + unsigned channels = FLAC__stream_decoder_get_channels(decoder); + unsigned bps = FLAC__stream_decoder_get_bits_per_sample(decoder); + const FLAC__StreamMetadata_SeekTable *seek_table = decoder->private_->has_seek_table? &decoder->private_->seek_table.data.seek_table : 0; + + /* use values from stream info if we didn't decode a frame */ + if(channels == 0) + channels = decoder->private_->stream_info.data.stream_info.channels; + if(bps == 0) + bps = decoder->private_->stream_info.data.stream_info.bits_per_sample; + + /* we are just guessing here */ + if(max_framesize > 0) + approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1; + /* + * Check if it's a known fixed-blocksize stream. Note that though + * the spec doesn't allow zeroes in the STREAMINFO block, we may + * never get a STREAMINFO block when decoding so the value of + * min_blocksize might be zero. + */ + else if(min_blocksize == max_blocksize && min_blocksize > 0) { + /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */ + approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64; + } + else + approx_bytes_per_frame = 4096 * channels * bps/8 + 64; + + /* + * First, we set an upper and lower bound on where in the + * stream we will search. For now we assume the worst case + * scenario, which is our best guess at the beginning of + * the first frame and end of the stream. + */ + lower_bound = first_frame_offset; + lower_bound_sample = 0; + upper_bound = stream_length; + upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/; + + /* + * Now we refine the bounds if we have a seektable with + * suitable points. Note that according to the spec they + * must be ordered by ascending sample number. + * + * Note: to protect against invalid seek tables we will ignore points + * that have frame_samples==0 or sample_number>=total_samples + */ + if(seek_table) { + FLAC__uint64 new_lower_bound = lower_bound; + FLAC__uint64 new_upper_bound = upper_bound; + FLAC__uint64 new_lower_bound_sample = lower_bound_sample; + FLAC__uint64 new_upper_bound_sample = upper_bound_sample; + + /* find the closest seek point <= target_sample, if it exists */ + for(i = (int)seek_table->num_points - 1; i >= 0; i--) { + if( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ + (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ + seek_table->points[i].sample_number <= target_sample + ) + break; + } + if(i >= 0) { /* i.e. we found a suitable seek point... */ + new_lower_bound = first_frame_offset + seek_table->points[i].stream_offset; + new_lower_bound_sample = seek_table->points[i].sample_number; + } + + /* find the closest seek point > target_sample, if it exists */ + for(i = 0; i < (int)seek_table->num_points; i++) { + if( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ + (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ + seek_table->points[i].sample_number > target_sample + ) + break; + } + if(i < (int)seek_table->num_points) { /* i.e. we found a suitable seek point... */ + new_upper_bound = first_frame_offset + seek_table->points[i].stream_offset; + new_upper_bound_sample = seek_table->points[i].sample_number; + } + /* final protection against unsorted seek tables; keep original values if bogus */ + if(new_upper_bound >= new_lower_bound) { + lower_bound = new_lower_bound; + upper_bound = new_upper_bound; + lower_bound_sample = new_lower_bound_sample; + upper_bound_sample = new_upper_bound_sample; + } + } + + FLAC__ASSERT(upper_bound_sample >= lower_bound_sample); + /* there are 2 insidious ways that the following equality occurs, which + * we need to fix: + * 1) total_samples is 0 (unknown) and target_sample is 0 + * 2) total_samples is 0 (unknown) and target_sample happens to be + * exactly equal to the last seek point in the seek table; this + * means there is no seek point above it, and upper_bound_samples + * remains equal to the estimate (of target_samples) we made above + * in either case it does not hurt to move upper_bound_sample up by 1 + */ + if(upper_bound_sample == lower_bound_sample) + upper_bound_sample++; + + decoder->private_->target_sample = target_sample; + while(1) { + /* check if the bounds are still ok */ + if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame; +#else + /* a little less accurate: */ + if(upper_bound - lower_bound < 0xffffffff) + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; + else /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8)) / ((upper_bound_sample - lower_bound_sample)>>16)) - approx_bytes_per_frame; +#endif + if(pos >= (FLAC__int64)upper_bound) + pos = (FLAC__int64)upper_bound - 1; + if(pos < (FLAC__int64)lower_bound) + pos = (FLAC__int64)lower_bound; + if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if(!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; + } + /* Now we need to get a frame. First we need to reset our + * unparseable_frame_count; if we get too many unparseable + * frames in a row, the read callback will return + * FLAC__STREAM_DECODER_READ_STATUS_ABORT, causing + * FLAC__stream_decoder_process_single() to return false. + */ + decoder->private_->unparseable_frame_count = 0; + if(!FLAC__stream_decoder_process_single(decoder) || + decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + /* our write callback will change the state when it gets to the target frame */ + /* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */ +#if 0 + /*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */ + if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM) + break; +#endif + if(!decoder->private_->is_seeking) + break; + + FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + this_frame_sample = decoder->private_->last_frame.header.number.sample_number; + + if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) { + if (pos == (FLAC__int64)lower_bound) { + /* can't move back any more than the first frame, something is fatally wrong */ + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + /* our last move backwards wasn't big enough, try again */ + approx_bytes_per_frame = approx_bytes_per_frame? approx_bytes_per_frame * 2 : 16; + continue; + } + /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */ + first_seek = false; + + /* make sure we are not seeking in corrupted stream */ + if (this_frame_sample < lower_bound_sample) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + + /* we need to narrow the search */ + if(target_sample < this_frame_sample) { + upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; +/*@@@@@@ what will decode position be if at end of stream? */ + if(!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + approx_bytes_per_frame = (unsigned)(2 * (upper_bound - pos) / 3 + 16); + } + else { /* target_sample >= this_frame_sample + this frame's blocksize */ + lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; + if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + approx_bytes_per_frame = (unsigned)(2 * (lower_bound - pos) / 3 + 16); + } + } + + return true; +} + +#if FLAC__HAS_OGG +FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) +{ + FLAC__uint64 left_pos = 0, right_pos = stream_length; + FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder); + FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1; + FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */ + FLAC__bool did_a_seek; + unsigned iteration = 0; + + /* In the first iterations, we will calculate the target byte position + * by the distance from the target sample to left_sample and + * right_sample (let's call it "proportional search"). After that, we + * will switch to binary search. + */ + unsigned BINARY_SEARCH_AFTER_ITERATION = 2; + + /* We will switch to a linear search once our current sample is less + * than this number of samples ahead of the target sample + */ + static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2; + + /* If the total number of samples is unknown, use a large value, and + * force binary search immediately. + */ + if(right_sample == 0) { + right_sample = (FLAC__uint64)(-1); + BINARY_SEARCH_AFTER_ITERATION = 0; + } + + decoder->private_->target_sample = target_sample; + for( ; ; iteration++) { + if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) { + if (iteration >= BINARY_SEARCH_AFTER_ITERATION) { + pos = (right_pos + left_pos) / 2; + } + else { +#ifndef FLAC__INTEGER_ONLY_LIBRARY + pos = (FLAC__uint64)((double)(target_sample - left_sample) / (double)(right_sample - left_sample) * (double)(right_pos - left_pos)); +#else + /* a little less accurate: */ + if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) + pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample)); + else /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16)); +#endif + /* @@@ TODO: might want to limit pos to some distance + * before EOF, to make sure we land before the last frame, + * thereby getting a this_frame_sample and so having a better + * estimate. + */ + } + + /* physical seek */ + if(decoder->private_->seek_callback((FLAC__StreamDecoder*)decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if(!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; + } + did_a_seek = true; + } + else + did_a_seek = false; + + decoder->private_->got_a_frame = false; + if(!FLAC__stream_decoder_process_single(decoder) || + decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if(!decoder->private_->got_a_frame) { + if(did_a_seek) { + /* this can happen if we seek to a point after the last frame; we drop + * to binary search right away in this case to avoid any wasted + * iterations of proportional search. + */ + right_pos = pos; + BINARY_SEARCH_AFTER_ITERATION = 0; + } + else { + /* this can probably only happen if total_samples is unknown and the + * target_sample is past the end of the stream + */ + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + } + /* our write callback will change the state when it gets to the target frame */ + else if(!decoder->private_->is_seeking) { + break; + } + else { + this_frame_sample = decoder->private_->last_frame.header.number.sample_number; + FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + + if (did_a_seek) { + if (this_frame_sample <= target_sample) { + /* The 'equal' case should not happen, since + * FLAC__stream_decoder_process_single() + * should recognize that it has hit the + * target sample and we would exit through + * the 'break' above. + */ + FLAC__ASSERT(this_frame_sample != target_sample); + + left_sample = this_frame_sample; + /* sanity check to avoid infinite loop */ + if (left_pos == pos) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + left_pos = pos; + } + else if(this_frame_sample > target_sample) { + right_sample = this_frame_sample; + /* sanity check to avoid infinite loop */ + if (right_pos == pos) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + right_pos = pos; + } + } + } + } + + return true; +} +#endif + +FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) +{ + (void)client_data; + + if(*bytes > 0) { + *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, decoder->private_->file); + if(ferror(decoder->private_->file)) + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + else if(*bytes == 0) + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + else + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + else + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ +} + +FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) +{ + (void)client_data; + + if(decoder->private_->file == stdin) + return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; +#ifdef __CELLOS_LV2__ + else if(fseek(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) +#else + else if(fseeko(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) +#endif + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + else + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; +} + +FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) +{ + FLAC__off_t pos; + (void)client_data; + + if(decoder->private_->file == stdin) + return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; +#ifdef __CELLOS_LV2__ + else if((pos = ftell(decoder->private_->file)) < 0) +#else + else if((pos = ftello(decoder->private_->file)) < 0) +#endif + return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + else { + *absolute_byte_offset = (FLAC__uint64)pos; + return FLAC__STREAM_DECODER_TELL_STATUS_OK; + } +} + +FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) +{ + struct flac_stat_s filestats; + (void)client_data; + + if(decoder->private_->file == stdin) + return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0) + return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; + else { + *stream_length = (FLAC__uint64)filestats.st_size; + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; + } +} + +FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data) +{ + (void)client_data; + + return feof(decoder->private_->file)? true : false; +} diff --git a/deps/flac-1.3.2/src/libFLAC/stream_encoder.c b/deps/flac-1.3.2/src/libFLAC/stream_encoder.c new file mode 100644 index 0000000..037b8cb --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/stream_encoder.c @@ -0,0 +1,4549 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> /* for malloc() */ +#include <string.h> /* for memcpy() */ +#include <sys/types.h> /* for off_t */ +#ifdef _WIN32 +#include <windows.h> /* for GetFileType() */ +#include <io.h> /* for _get_osfhandle() */ +#endif +#include "share/compat.h" +#include "FLAC/assert.h" +#include "FLAC/stream_decoder.h" +#include "protected/stream_encoder.h" +#include "private/bitwriter.h" +#include "private/bitmath.h" +#include "private/crc.h" +#include "private/cpu.h" +#include "private/fixed.h" +#include "private/format.h" +#include "private/lpc.h" +#include "private/md5.h" +#include "private/memory.h" +#include "private/macros.h" +#if FLAC__HAS_OGG +#include "private/ogg_helper.h" +#include "private/ogg_mapping.h" +#endif +#include "private/stream_encoder.h" +#include "private/stream_encoder_framing.h" +#include "private/window.h" +#include "share/alloc.h" +#include "share/private.h" + + +/* Exact Rice codeword length calculation is off by default. The simple + * (and fast) estimation (of how many bits a residual value will be + * encoded with) in this encoder is very good, almost always yielding + * compression within 0.1% of exact calculation. + */ +#undef EXACT_RICE_BITS_CALCULATION +/* Rice parameter searching is off by default. The simple (and fast) + * parameter estimation in this encoder is very good, almost always + * yielding compression within 0.1% of the optimal parameters. + */ +#undef ENABLE_RICE_PARAMETER_SEARCH + + +typedef struct { + FLAC__int32 *data[FLAC__MAX_CHANNELS]; + unsigned size; /* of each data[] in samples */ + unsigned tail; +} verify_input_fifo; + +typedef struct { + const FLAC__byte *data; + unsigned capacity; + unsigned bytes; +} verify_output; + +typedef enum { + ENCODER_IN_MAGIC = 0, + ENCODER_IN_METADATA = 1, + ENCODER_IN_AUDIO = 2 +} EncoderStateHint; + +static struct CompressionLevels { + FLAC__bool do_mid_side_stereo; + FLAC__bool loose_mid_side_stereo; + unsigned max_lpc_order; + unsigned qlp_coeff_precision; + FLAC__bool do_qlp_coeff_prec_search; + FLAC__bool do_escape_coding; + FLAC__bool do_exhaustive_model_search; + unsigned min_residual_partition_order; + unsigned max_residual_partition_order; + unsigned rice_parameter_search_dist; + const char *apodization; +} compression_levels_[] = { + { false, false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, + { true , true , 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, + { true , false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, + { false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, + { true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, + { true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" }, + { true , false, 8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" }, + { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" }, + { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2);punchout_tukey(3)" } + /* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */ +}; + + +/*********************************************************************** + * + * Private class method prototypes + * + ***********************************************************************/ + +static void set_defaults_(FLAC__StreamEncoder *encoder); +static void free_(FLAC__StreamEncoder *encoder); +static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize); +static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block); +static FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block); +static void update_metadata_(const FLAC__StreamEncoder *encoder); +#if FLAC__HAS_OGG +static void update_ogg_metadata_(FLAC__StreamEncoder *encoder); +#endif +static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block); +static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block); + +static FLAC__bool process_subframe_( + FLAC__StreamEncoder *encoder, + unsigned min_partition_order, + unsigned max_partition_order, + const FLAC__FrameHeader *frame_header, + unsigned subframe_bps, + const FLAC__int32 integer_signal[], + FLAC__Subframe *subframe[2], + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], + FLAC__int32 *residual[2], + unsigned *best_subframe, + unsigned *best_bits +); + +static FLAC__bool add_subframe_( + FLAC__StreamEncoder *encoder, + unsigned blocksize, + unsigned subframe_bps, + const FLAC__Subframe *subframe, + FLAC__BitWriter *frame +); + +static unsigned evaluate_constant_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal, + unsigned blocksize, + unsigned subframe_bps, + FLAC__Subframe *subframe +); + +static unsigned evaluate_fixed_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal[], + FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned raw_bits_per_partition[], + unsigned blocksize, + unsigned subframe_bps, + unsigned order, + unsigned rice_parameter, + unsigned rice_parameter_limit, + unsigned min_partition_order, + unsigned max_partition_order, + FLAC__bool do_escape_coding, + unsigned rice_parameter_search_dist, + FLAC__Subframe *subframe, + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents +); + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +static unsigned evaluate_lpc_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal[], + FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned raw_bits_per_partition[], + const FLAC__real lp_coeff[], + unsigned blocksize, + unsigned subframe_bps, + unsigned order, + unsigned qlp_coeff_precision, + unsigned rice_parameter, + unsigned rice_parameter_limit, + unsigned min_partition_order, + unsigned max_partition_order, + FLAC__bool do_escape_coding, + unsigned rice_parameter_search_dist, + FLAC__Subframe *subframe, + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents +); +#endif + +static unsigned evaluate_verbatim_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal[], + unsigned blocksize, + unsigned subframe_bps, + FLAC__Subframe *subframe +); + +static unsigned find_best_partition_order_( + struct FLAC__StreamEncoderPrivate *private_, + const FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned raw_bits_per_partition[], + unsigned residual_samples, + unsigned predictor_order, + unsigned rice_parameter, + unsigned rice_parameter_limit, + unsigned min_partition_order, + unsigned max_partition_order, + unsigned bps, + FLAC__bool do_escape_coding, + unsigned rice_parameter_search_dist, + FLAC__EntropyCodingMethod *best_ecm +); + +static void precompute_partition_info_sums_( + const FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, + unsigned predictor_order, + unsigned min_partition_order, + unsigned max_partition_order, + unsigned bps +); + +static void precompute_partition_info_escapes_( + const FLAC__int32 residual[], + unsigned raw_bits_per_partition[], + unsigned residual_samples, + unsigned predictor_order, + unsigned min_partition_order, + unsigned max_partition_order +); + +static FLAC__bool set_partitioned_rice_( +#ifdef EXACT_RICE_BITS_CALCULATION + const FLAC__int32 residual[], +#endif + const FLAC__uint64 abs_residual_partition_sums[], + const unsigned raw_bits_per_partition[], + const unsigned residual_samples, + const unsigned predictor_order, + const unsigned suggested_rice_parameter, + const unsigned rice_parameter_limit, + const unsigned rice_parameter_search_dist, + const unsigned partition_order, + const FLAC__bool search_for_escapes, + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, + unsigned *bits +); + +static unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples); + +/* verify-related routines: */ +static void append_to_verify_fifo_( + verify_input_fifo *fifo, + const FLAC__int32 * const input[], + unsigned input_offset, + unsigned channels, + unsigned wide_samples +); + +static void append_to_verify_fifo_interleaved_( + verify_input_fifo *fifo, + const FLAC__int32 input[], + unsigned input_offset, + unsigned channels, + unsigned wide_samples +); + +static FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); +static FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); +static void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); +static void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); + +static FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); +static FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); +static FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); +static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); +static FILE *get_binary_stdout_(void); + + +/*********************************************************************** + * + * Private class data + * + ***********************************************************************/ + +typedef struct FLAC__StreamEncoderPrivate { + unsigned input_capacity; /* current size (in samples) of the signal and residual buffers */ + FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */ + FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY + FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) the floating-point version of the input signal */ + FLAC__real *real_signal_mid_side[2]; /* (@@@ currently unused) the floating-point version of the mid-side input signal (stereo only) */ + FLAC__real *window[FLAC__MAX_APODIZATION_FUNCTIONS]; /* the pre-computed floating-point window for each apodization function */ + FLAC__real *windowed_signal; /* the integer_signal[] * current window[] */ +#endif + unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */ + unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */ + FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */ + FLAC__int32 *residual_workspace_mid_side[2][2]; + FLAC__Subframe subframe_workspace[FLAC__MAX_CHANNELS][2]; + FLAC__Subframe subframe_workspace_mid_side[2][2]; + FLAC__Subframe *subframe_workspace_ptr[FLAC__MAX_CHANNELS][2]; + FLAC__Subframe *subframe_workspace_ptr_mid_side[2][2]; + FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace[FLAC__MAX_CHANNELS][2]; + FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace_mid_side[FLAC__MAX_CHANNELS][2]; + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr[FLAC__MAX_CHANNELS][2]; + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr_mid_side[FLAC__MAX_CHANNELS][2]; + unsigned best_subframe[FLAC__MAX_CHANNELS]; /* index (0 or 1) into 2nd dimension of the above workspaces */ + unsigned best_subframe_mid_side[2]; + unsigned best_subframe_bits[FLAC__MAX_CHANNELS]; /* size in bits of the best subframe for each channel */ + unsigned best_subframe_bits_mid_side[2]; + FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */ + unsigned *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */ + FLAC__BitWriter *frame; /* the current frame being worked on */ + unsigned loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */ + unsigned loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */ + FLAC__ChannelAssignment last_channel_assignment; + FLAC__StreamMetadata streaminfo; /* scratchpad for STREAMINFO as it is built */ + FLAC__StreamMetadata_SeekTable *seek_table; /* pointer into encoder->protected_->metadata_ where the seek table is */ + unsigned current_sample_number; + unsigned current_frame_number; + FLAC__MD5Context md5context; + FLAC__CPUInfo cpuinfo; + void (*local_precompute_partition_info_sums)(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); +#ifndef FLAC__INTEGER_ONLY_LIBRARY + unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); + unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#else + unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); + unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#endif +#ifndef FLAC__INTEGER_ONLY_LIBRARY + void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); + void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); + void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); + void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +#endif + FLAC__bool disable_constant_subframes; + FLAC__bool disable_fixed_subframes; + FLAC__bool disable_verbatim_subframes; + FLAC__bool is_ogg; + FLAC__StreamEncoderReadCallback read_callback; /* currently only needed for Ogg FLAC */ + FLAC__StreamEncoderSeekCallback seek_callback; + FLAC__StreamEncoderTellCallback tell_callback; + FLAC__StreamEncoderWriteCallback write_callback; + FLAC__StreamEncoderMetadataCallback metadata_callback; + FLAC__StreamEncoderProgressCallback progress_callback; + void *client_data; + unsigned first_seekpoint_to_check; + FILE *file; /* only used when encoding to a file */ + FLAC__uint64 bytes_written; + FLAC__uint64 samples_written; + unsigned frames_written; + unsigned total_frames_estimate; + /* unaligned (original) pointers to allocated data */ + FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS]; + FLAC__int32 *integer_signal_mid_side_unaligned[2]; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) */ + FLAC__real *real_signal_mid_side_unaligned[2]; /* (@@@ currently unused) */ + FLAC__real *window_unaligned[FLAC__MAX_APODIZATION_FUNCTIONS]; + FLAC__real *windowed_signal_unaligned; +#endif + FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2]; + FLAC__int32 *residual_workspace_mid_side_unaligned[2][2]; + FLAC__uint64 *abs_residual_partition_sums_unaligned; + unsigned *raw_bits_per_partition_unaligned; + /* + * These fields have been moved here from private function local + * declarations merely to save stack space during encoding. + */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY + FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */ +#endif + FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */ + /* + * The data for the verify section + */ + struct { + FLAC__StreamDecoder *decoder; + EncoderStateHint state_hint; + FLAC__bool needs_magic_hack; + verify_input_fifo input_fifo; + verify_output output; + struct { + FLAC__uint64 absolute_sample; + unsigned frame_number; + unsigned channel; + unsigned sample; + FLAC__int32 expected; + FLAC__int32 got; + } error_stats; + } verify; + FLAC__bool is_being_deleted; /* if true, call to ..._finish() from ..._delete() will not call the callbacks */ +} FLAC__StreamEncoderPrivate; + +/*********************************************************************** + * + * Public static class data + * + ***********************************************************************/ + +FLAC_API const char * const FLAC__StreamEncoderStateString[] = { + "FLAC__STREAM_ENCODER_OK", + "FLAC__STREAM_ENCODER_UNINITIALIZED", + "FLAC__STREAM_ENCODER_OGG_ERROR", + "FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR", + "FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA", + "FLAC__STREAM_ENCODER_CLIENT_ERROR", + "FLAC__STREAM_ENCODER_IO_ERROR", + "FLAC__STREAM_ENCODER_FRAMING_ERROR", + "FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR" +}; + +FLAC_API const char * const FLAC__StreamEncoderInitStatusString[] = { + "FLAC__STREAM_ENCODER_INIT_STATUS_OK", + "FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR", + "FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION", + "FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER", + "FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE", + "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA", + "FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED" +}; + +FLAC_API const char * const FLAC__StreamEncoderReadStatusString[] = { + "FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE", + "FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM", + "FLAC__STREAM_ENCODER_READ_STATUS_ABORT", + "FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED" +}; + +FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = { + "FLAC__STREAM_ENCODER_WRITE_STATUS_OK", + "FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR" +}; + +FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[] = { + "FLAC__STREAM_ENCODER_SEEK_STATUS_OK", + "FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR", + "FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED" +}; + +FLAC_API const char * const FLAC__StreamEncoderTellStatusString[] = { + "FLAC__STREAM_ENCODER_TELL_STATUS_OK", + "FLAC__STREAM_ENCODER_TELL_STATUS_ERROR", + "FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED" +}; + +/* Number of samples that will be overread to watch for end of stream. By + * 'overread', we mean that the FLAC__stream_encoder_process*() calls will + * always try to read blocksize+1 samples before encoding a block, so that + * even if the stream has a total sample count that is an integral multiple + * of the blocksize, we will still notice when we are encoding the last + * block. This is needed, for example, to correctly set the end-of-stream + * marker in Ogg FLAC. + * + * WATCHOUT: some parts of the code assert that OVERREAD_ == 1 and there's + * not really any reason to change it. + */ +static const unsigned OVERREAD_ = 1; + +/*********************************************************************** + * + * Class constructor/destructor + * + */ +FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void) +{ + FLAC__StreamEncoder *encoder; + unsigned i; + + FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ + + encoder = calloc(1, sizeof(FLAC__StreamEncoder)); + if(encoder == 0) { + return 0; + } + + encoder->protected_ = calloc(1, sizeof(FLAC__StreamEncoderProtected)); + if(encoder->protected_ == 0) { + free(encoder); + return 0; + } + + encoder->private_ = calloc(1, sizeof(FLAC__StreamEncoderPrivate)); + if(encoder->private_ == 0) { + free(encoder->protected_); + free(encoder); + return 0; + } + + encoder->private_->frame = FLAC__bitwriter_new(); + if(encoder->private_->frame == 0) { + free(encoder->private_); + free(encoder->protected_); + free(encoder); + return 0; + } + + encoder->private_->file = 0; + + set_defaults_(encoder); + + encoder->private_->is_being_deleted = false; + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + encoder->private_->subframe_workspace_ptr[i][0] = &encoder->private_->subframe_workspace[i][0]; + encoder->private_->subframe_workspace_ptr[i][1] = &encoder->private_->subframe_workspace[i][1]; + } + for(i = 0; i < 2; i++) { + encoder->private_->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->subframe_workspace_mid_side[i][0]; + encoder->private_->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->subframe_workspace_mid_side[i][1]; + } + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + encoder->private_->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->partitioned_rice_contents_workspace[i][0]; + encoder->private_->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->partitioned_rice_contents_workspace[i][1]; + } + for(i = 0; i < 2; i++) { + encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]; + encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]; + } + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][0]); + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][1]); + } + for(i = 0; i < 2; i++) { + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]); + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]); + } + for(i = 0; i < 2; i++) + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]); + + encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; + + return encoder; +} + +FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) +{ + unsigned i; + + if (encoder == NULL) + return ; + + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->private_->frame); + + encoder->private_->is_being_deleted = true; + + (void)FLAC__stream_encoder_finish(encoder); + + if(0 != encoder->private_->verify.decoder) + FLAC__stream_decoder_delete(encoder->private_->verify.decoder); + + for(i = 0; i < FLAC__MAX_CHANNELS; i++) { + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][0]); + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][1]); + } + for(i = 0; i < 2; i++) { + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]); + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]); + } + for(i = 0; i < 2; i++) + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_extra[i]); + + FLAC__bitwriter_delete(encoder->private_->frame); + free(encoder->private_); + free(encoder->protected_); + free(encoder); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +static FLAC__StreamEncoderInitStatus init_stream_internal_( + FLAC__StreamEncoder *encoder, + FLAC__StreamEncoderReadCallback read_callback, + FLAC__StreamEncoderWriteCallback write_callback, + FLAC__StreamEncoderSeekCallback seek_callback, + FLAC__StreamEncoderTellCallback tell_callback, + FLAC__StreamEncoderMetadataCallback metadata_callback, + void *client_data, + FLAC__bool is_ogg +) +{ + unsigned i; + FLAC__bool metadata_has_seektable, metadata_has_vorbis_comment, metadata_picture_has_type1, metadata_picture_has_type2; + + FLAC__ASSERT(0 != encoder); + + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; + + if(FLAC__HAS_OGG == 0 && is_ogg) + return FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER; + + if(0 == write_callback || (seek_callback && 0 == tell_callback)) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS; + + if(encoder->protected_->channels == 0 || encoder->protected_->channels > FLAC__MAX_CHANNELS) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS; + + if(encoder->protected_->channels != 2) { + encoder->protected_->do_mid_side_stereo = false; + encoder->protected_->loose_mid_side_stereo = false; + } + else if(!encoder->protected_->do_mid_side_stereo) + encoder->protected_->loose_mid_side_stereo = false; + + if(encoder->protected_->bits_per_sample >= 32) + encoder->protected_->do_mid_side_stereo = false; /* since we currenty do 32-bit math, the side channel would have 33 bps and overflow */ + + if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE; + + if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate)) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE; + + if(encoder->protected_->blocksize == 0) { + if(encoder->protected_->max_lpc_order == 0) + encoder->protected_->blocksize = 1152; + else + encoder->protected_->blocksize = 4096; + } + + if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE; + + if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER; + + if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order) + return FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER; + + if(encoder->protected_->qlp_coeff_precision == 0) { + if(encoder->protected_->bits_per_sample < 16) { + /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */ + /* @@@ until then we'll make a guess */ + encoder->protected_->qlp_coeff_precision = flac_max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2); + } + else if(encoder->protected_->bits_per_sample == 16) { + if(encoder->protected_->blocksize <= 192) + encoder->protected_->qlp_coeff_precision = 7; + else if(encoder->protected_->blocksize <= 384) + encoder->protected_->qlp_coeff_precision = 8; + else if(encoder->protected_->blocksize <= 576) + encoder->protected_->qlp_coeff_precision = 9; + else if(encoder->protected_->blocksize <= 1152) + encoder->protected_->qlp_coeff_precision = 10; + else if(encoder->protected_->blocksize <= 2304) + encoder->protected_->qlp_coeff_precision = 11; + else if(encoder->protected_->blocksize <= 4608) + encoder->protected_->qlp_coeff_precision = 12; + else + encoder->protected_->qlp_coeff_precision = 13; + } + else { + if(encoder->protected_->blocksize <= 384) + encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-2; + else if(encoder->protected_->blocksize <= 1152) + encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-1; + else + encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; + } + FLAC__ASSERT(encoder->protected_->qlp_coeff_precision <= FLAC__MAX_QLP_COEFF_PRECISION); + } + else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision > FLAC__MAX_QLP_COEFF_PRECISION) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION; + + if(encoder->protected_->streamable_subset) { + if(!FLAC__format_blocksize_is_subset(encoder->protected_->blocksize, encoder->protected_->sample_rate)) + return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; + if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate)) + return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; + if( + encoder->protected_->bits_per_sample != 8 && + encoder->protected_->bits_per_sample != 12 && + encoder->protected_->bits_per_sample != 16 && + encoder->protected_->bits_per_sample != 20 && + encoder->protected_->bits_per_sample != 24 + ) + return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; + if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER) + return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; + if( + encoder->protected_->sample_rate <= 48000 && + ( + encoder->protected_->blocksize > FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ || + encoder->protected_->max_lpc_order > FLAC__SUBSET_MAX_LPC_ORDER_48000HZ + ) + ) { + return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; + } + } + + if(encoder->protected_->max_residual_partition_order >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) + encoder->protected_->max_residual_partition_order = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN) - 1; + if(encoder->protected_->min_residual_partition_order >= encoder->protected_->max_residual_partition_order) + encoder->protected_->min_residual_partition_order = encoder->protected_->max_residual_partition_order; + +#if FLAC__HAS_OGG + /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */ + if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) { + unsigned i1; + for(i1 = 1; i1 < encoder->protected_->num_metadata_blocks; i1++) { + if(0 != encoder->protected_->metadata[i1] && encoder->protected_->metadata[i1]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + FLAC__StreamMetadata *vc = encoder->protected_->metadata[i1]; + for( ; i1 > 0; i1--) + encoder->protected_->metadata[i1] = encoder->protected_->metadata[i1-1]; + encoder->protected_->metadata[0] = vc; + break; + } + } + } +#endif + /* keep track of any SEEKTABLE block */ + if(0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) { + unsigned i2; + for(i2 = 0; i2 < encoder->protected_->num_metadata_blocks; i2++) { + if(0 != encoder->protected_->metadata[i2] && encoder->protected_->metadata[i2]->type == FLAC__METADATA_TYPE_SEEKTABLE) { + encoder->private_->seek_table = &encoder->protected_->metadata[i2]->data.seek_table; + break; /* take only the first one */ + } + } + } + + /* validate metadata */ + if(0 == encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + metadata_has_seektable = false; + metadata_has_vorbis_comment = false; + metadata_picture_has_type1 = false; + metadata_picture_has_type2 = false; + for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { + const FLAC__StreamMetadata *m = encoder->protected_->metadata[i]; + if(m->type == FLAC__METADATA_TYPE_STREAMINFO) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + else if(m->type == FLAC__METADATA_TYPE_SEEKTABLE) { + if(metadata_has_seektable) /* only one is allowed */ + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + metadata_has_seektable = true; + if(!FLAC__format_seektable_is_legal(&m->data.seek_table)) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + } + else if(m->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + if(metadata_has_vorbis_comment) /* only one is allowed */ + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + metadata_has_vorbis_comment = true; + } + else if(m->type == FLAC__METADATA_TYPE_CUESHEET) { + if(!FLAC__format_cuesheet_is_legal(&m->data.cue_sheet, m->data.cue_sheet.is_cd, /*violation=*/0)) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + } + else if(m->type == FLAC__METADATA_TYPE_PICTURE) { + if(!FLAC__format_picture_is_legal(&m->data.picture, /*violation=*/0)) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD) { + if(metadata_picture_has_type1) /* there should only be 1 per stream */ + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + metadata_picture_has_type1 = true; + /* standard icon must be 32x32 pixel PNG */ + if( + m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD && + ( + (strcmp(m->data.picture.mime_type, "image/png") && strcmp(m->data.picture.mime_type, "-->")) || + m->data.picture.width != 32 || + m->data.picture.height != 32 + ) + ) + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + } + else if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON) { + if(metadata_picture_has_type2) /* there should only be 1 per stream */ + return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; + metadata_picture_has_type2 = true; + } + } + } + + encoder->private_->input_capacity = 0; + for(i = 0; i < encoder->protected_->channels; i++) { + encoder->private_->integer_signal_unaligned[i] = encoder->private_->integer_signal[i] = 0; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->private_->real_signal_unaligned[i] = encoder->private_->real_signal[i] = 0; +#endif + } + for(i = 0; i < 2; i++) { + encoder->private_->integer_signal_mid_side_unaligned[i] = encoder->private_->integer_signal_mid_side[i] = 0; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0; +#endif + } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + for(i = 0; i < encoder->protected_->num_apodizations; i++) + encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0; + encoder->private_->windowed_signal_unaligned = encoder->private_->windowed_signal = 0; +#endif + for(i = 0; i < encoder->protected_->channels; i++) { + encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0; + encoder->private_->residual_workspace_unaligned[i][1] = encoder->private_->residual_workspace[i][1] = 0; + encoder->private_->best_subframe[i] = 0; + } + for(i = 0; i < 2; i++) { + encoder->private_->residual_workspace_mid_side_unaligned[i][0] = encoder->private_->residual_workspace_mid_side[i][0] = 0; + encoder->private_->residual_workspace_mid_side_unaligned[i][1] = encoder->private_->residual_workspace_mid_side[i][1] = 0; + encoder->private_->best_subframe_mid_side[i] = 0; + } + encoder->private_->abs_residual_partition_sums_unaligned = encoder->private_->abs_residual_partition_sums = 0; + encoder->private_->raw_bits_per_partition_unaligned = encoder->private_->raw_bits_per_partition = 0; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->private_->loose_mid_side_stereo_frames = (unsigned)((double)encoder->protected_->sample_rate * 0.4 / (double)encoder->protected_->blocksize + 0.5); +#else + /* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */ + /* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply÷ by hand */ + FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350); + FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535); + FLAC__ASSERT(encoder->protected_->sample_rate <= 655350); + FLAC__ASSERT(encoder->protected_->blocksize <= 65535); + encoder->private_->loose_mid_side_stereo_frames = (unsigned)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF); +#endif + if(encoder->private_->loose_mid_side_stereo_frames == 0) + encoder->private_->loose_mid_side_stereo_frames = 1; + encoder->private_->loose_mid_side_stereo_frame_count = 0; + encoder->private_->current_sample_number = 0; + encoder->private_->current_frame_number = 0; + + /* + * get the CPU info and set the function pointers + */ + FLAC__cpu_info(&encoder->private_->cpuinfo); + /* first default to the non-asm routines */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; +#endif + encoder->private_->local_precompute_partition_info_sums = precompute_partition_info_sums_; + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients; +#endif + /* now override with asm where appropriate */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY +# ifndef FLAC__NO_ASM + if(encoder->private_->cpuinfo.use_asm) { +# ifdef FLAC__CPU_IA32 + FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); +# ifdef FLAC__HAS_NASM + if(encoder->private_->cpuinfo.ia32.sse) { + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old; + else + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; + } + else + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; + + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ + if(encoder->private_->cpuinfo.ia32.mmx) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx; + } + else { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; + } + + if(encoder->private_->cpuinfo.ia32.mmx && encoder->private_->cpuinfo.ia32.cmov) + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; +# endif /* FLAC__HAS_NASM */ +# if FLAC__HAS_X86INTRIN +# if defined FLAC__SSE_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse) { + if(encoder->private_->cpuinfo.ia32.sse42 || !encoder->private_->cpuinfo.ia32.intel) { /* use new autocorrelation functions */ + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new; + else + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; + } + else { /* use old autocorrelation functions */ + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old; + else + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; + } + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse2) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; + } +# endif +# ifdef FLAC__SSE4_1_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse41) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41; + } +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.avx2) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + if (encoder->private_->cpuinfo.ia32.sse2) { + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2; + } +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if (encoder->private_->cpuinfo.ia32.ssse3) { + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3; + } +# endif +# endif /* FLAC__HAS_X86INTRIN */ +# elif defined FLAC__CPU_X86_64 + FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); +# if FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE_SUPPORTED + if(encoder->private_->cpuinfo.x86.sse42 || !encoder->private_->cpuinfo.x86.intel) { /* use new autocorrelation functions */ + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new; + } + else { + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old; + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; +# endif +# ifdef FLAC__SSE4_1_SUPPORTED + if(encoder->private_->cpuinfo.x86.sse41) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41; + } +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.x86.avx2) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2; +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if (encoder->private_->cpuinfo.x86.ssse3) { + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3; + } +# endif +# endif /* FLAC__HAS_X86INTRIN */ +# endif /* FLAC__CPU_... */ + } +# endif /* !FLAC__NO_ASM */ +#endif /* !FLAC__INTEGER_ONLY_LIBRARY */ +#if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN + if(encoder->private_->cpuinfo.use_asm) { +# if defined FLAC__CPU_IA32 +# ifdef FLAC__SSE2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse2) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if(encoder->private_->cpuinfo.ia32.ssse3) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3; +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.avx2) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; +# endif +# elif defined FLAC__CPU_X86_64 +# ifdef FLAC__SSE2_SUPPORTED + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if(encoder->private_->cpuinfo.x86.ssse3) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3; +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.x86.avx2) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; +# endif +# endif /* FLAC__CPU_... */ + } +#endif /* !FLAC__NO_ASM && FLAC__HAS_X86INTRIN */ + + /* set state to OK; from here on, errors are fatal and we'll override the state then */ + encoder->protected_->state = FLAC__STREAM_ENCODER_OK; + +#if FLAC__HAS_OGG + encoder->private_->is_ogg = is_ogg; + if(is_ogg && !FLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } +#endif + + encoder->private_->read_callback = read_callback; + encoder->private_->write_callback = write_callback; + encoder->private_->seek_callback = seek_callback; + encoder->private_->tell_callback = tell_callback; + encoder->private_->metadata_callback = metadata_callback; + encoder->private_->client_data = client_data; + + if(!resize_buffers_(encoder, encoder->protected_->blocksize)) { + /* the above function sets the state for us in case of an error */ + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + if(!FLAC__bitwriter_init(encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + /* + * Set up the verify stuff if necessary + */ + if(encoder->protected_->verify) { + /* + * First, set up the fifo which will hold the + * original signal to compare against + */ + encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_; + for(i = 0; i < encoder->protected_->channels; i++) { + if(0 == (encoder->private_->verify.input_fifo.data[i] = safe_malloc_mul_2op_p(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + } + encoder->private_->verify.input_fifo.tail = 0; + + /* + * Now set up a stream decoder for verification + */ + if(0 == encoder->private_->verify.decoder) { + encoder->private_->verify.decoder = FLAC__stream_decoder_new(); + if(0 == encoder->private_->verify.decoder) { + encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + } + + if(FLAC__stream_decoder_init_stream(encoder->private_->verify.decoder, verify_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, verify_write_callback_, verify_metadata_callback_, verify_error_callback_, /*client_data=*/encoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + } + encoder->private_->verify.error_stats.absolute_sample = 0; + encoder->private_->verify.error_stats.frame_number = 0; + encoder->private_->verify.error_stats.channel = 0; + encoder->private_->verify.error_stats.sample = 0; + encoder->private_->verify.error_stats.expected = 0; + encoder->private_->verify.error_stats.got = 0; + + /* + * These must be done before we write any metadata, because that + * calls the write_callback, which uses these values. + */ + encoder->private_->first_seekpoint_to_check = 0; + encoder->private_->samples_written = 0; + encoder->protected_->streaminfo_offset = 0; + encoder->protected_->seektable_offset = 0; + encoder->protected_->audio_offset = 0; + + /* + * write the stream header + */ + if(encoder->protected_->verify) + encoder->private_->verify.state_hint = ENCODER_IN_MAGIC; + if(!FLAC__bitwriter_write_raw_uint32(encoder->private_->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) { + /* the above function sets the state for us in case of an error */ + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + /* + * write the STREAMINFO metadata block + */ + if(encoder->protected_->verify) + encoder->private_->verify.state_hint = ENCODER_IN_METADATA; + encoder->private_->streaminfo.type = FLAC__METADATA_TYPE_STREAMINFO; + encoder->private_->streaminfo.is_last = false; /* we will have at a minimum a VORBIS_COMMENT afterwards */ + encoder->private_->streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; + encoder->private_->streaminfo.data.stream_info.min_blocksize = encoder->protected_->blocksize; /* this encoder uses the same blocksize for the whole stream */ + encoder->private_->streaminfo.data.stream_info.max_blocksize = encoder->protected_->blocksize; + encoder->private_->streaminfo.data.stream_info.min_framesize = 0; /* we don't know this yet; have to fill it in later */ + encoder->private_->streaminfo.data.stream_info.max_framesize = 0; /* we don't know this yet; have to fill it in later */ + encoder->private_->streaminfo.data.stream_info.sample_rate = encoder->protected_->sample_rate; + encoder->private_->streaminfo.data.stream_info.channels = encoder->protected_->channels; + encoder->private_->streaminfo.data.stream_info.bits_per_sample = encoder->protected_->bits_per_sample; + encoder->private_->streaminfo.data.stream_info.total_samples = encoder->protected_->total_samples_estimate; /* we will replace this later with the real total */ + memset(encoder->private_->streaminfo.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */ + if(encoder->protected_->do_md5) + FLAC__MD5Init(&encoder->private_->md5context); + if(!FLAC__add_metadata_block(&encoder->private_->streaminfo, encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) { + /* the above function sets the state for us in case of an error */ + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + /* + * Now that the STREAMINFO block is written, we can init this to an + * absurdly-high value... + */ + encoder->private_->streaminfo.data.stream_info.min_framesize = (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN) - 1; + /* ... and clear this to 0 */ + encoder->private_->streaminfo.data.stream_info.total_samples = 0; + + /* + * Check to see if the supplied metadata contains a VORBIS_COMMENT; + * if not, we will write an empty one (FLAC__add_metadata_block() + * automatically supplies the vendor string). + * + * WATCHOUT: the Ogg FLAC mapping requires us to write this block after + * the STREAMINFO. (In the case that metadata_has_vorbis_comment is + * true it will have already insured that the metadata list is properly + * ordered.) + */ + if(!metadata_has_vorbis_comment) { + FLAC__StreamMetadata vorbis_comment; + vorbis_comment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT; + vorbis_comment.is_last = (encoder->protected_->num_metadata_blocks == 0); + vorbis_comment.length = 4 + 4; /* MAGIC NUMBER */ + vorbis_comment.data.vorbis_comment.vendor_string.length = 0; + vorbis_comment.data.vorbis_comment.vendor_string.entry = 0; + vorbis_comment.data.vorbis_comment.num_comments = 0; + vorbis_comment.data.vorbis_comment.comments = 0; + if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) { + /* the above function sets the state for us in case of an error */ + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + } + + /* + * write the user's metadata blocks + */ + for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { + encoder->protected_->metadata[i]->is_last = (i == encoder->protected_->num_metadata_blocks - 1); + if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) { + /* the above function sets the state for us in case of an error */ + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + } + + /* now that all the metadata is written, we save the stream offset */ + if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + if(encoder->protected_->verify) + encoder->private_->verify.state_hint = ENCODER_IN_AUDIO; + + return FLAC__STREAM_ENCODER_INIT_STATUS_OK; +} + +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream( + FLAC__StreamEncoder *encoder, + FLAC__StreamEncoderWriteCallback write_callback, + FLAC__StreamEncoderSeekCallback seek_callback, + FLAC__StreamEncoderTellCallback tell_callback, + FLAC__StreamEncoderMetadataCallback metadata_callback, + void *client_data +) +{ + return init_stream_internal_( + encoder, + /*read_callback=*/0, + write_callback, + seek_callback, + tell_callback, + metadata_callback, + client_data, + /*is_ogg=*/false + ); +} + +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream( + FLAC__StreamEncoder *encoder, + FLAC__StreamEncoderReadCallback read_callback, + FLAC__StreamEncoderWriteCallback write_callback, + FLAC__StreamEncoderSeekCallback seek_callback, + FLAC__StreamEncoderTellCallback tell_callback, + FLAC__StreamEncoderMetadataCallback metadata_callback, + void *client_data +) +{ + return init_stream_internal_( + encoder, + read_callback, + write_callback, + seek_callback, + tell_callback, + metadata_callback, + client_data, + /*is_ogg=*/true + ); +} + +static FLAC__StreamEncoderInitStatus init_FILE_internal_( + FLAC__StreamEncoder *encoder, + FILE *file, + FLAC__StreamEncoderProgressCallback progress_callback, + void *client_data, + FLAC__bool is_ogg +) +{ + FLAC__StreamEncoderInitStatus init_status; + + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != file); + + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; + + /* double protection */ + if(file == 0) { + encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + /* + * To make sure that our file does not go unclosed after an error, we + * must assign the FILE pointer before any further error can occur in + * this routine. + */ + if(file == stdout) + file = get_binary_stdout_(); /* just to be safe */ + +#ifdef _WIN32 + /* + * Windows can suffer quite badly from disk fragmentation. This can be + * reduced significantly by setting the output buffer size to be 10MB. + */ + if(GetFileType((HANDLE)_get_osfhandle(_fileno(file))) == FILE_TYPE_DISK) + setvbuf(file, NULL, _IOFBF, 10*1024*1024); +#endif + encoder->private_->file = file; + + encoder->private_->progress_callback = progress_callback; + encoder->private_->bytes_written = 0; + encoder->private_->samples_written = 0; + encoder->private_->frames_written = 0; + + init_status = init_stream_internal_( + encoder, + encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_ : 0, + file_write_callback_, + encoder->private_->file == stdout? 0 : file_seek_callback_, + encoder->private_->file == stdout? 0 : file_tell_callback_, + /*metadata_callback=*/0, + client_data, + is_ogg + ); + if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { + /* the above function sets the state for us in case of an error */ + return init_status; + } + + { + unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder); + + FLAC__ASSERT(blocksize != 0); + encoder->private_->total_frames_estimate = (unsigned)((FLAC__stream_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize); + } + + return init_status; +} + +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE( + FLAC__StreamEncoder *encoder, + FILE *file, + FLAC__StreamEncoderProgressCallback progress_callback, + void *client_data +) +{ + return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/false); +} + +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE( + FLAC__StreamEncoder *encoder, + FILE *file, + FLAC__StreamEncoderProgressCallback progress_callback, + void *client_data +) +{ + return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/true); +} + +static FLAC__StreamEncoderInitStatus init_file_internal_( + FLAC__StreamEncoder *encoder, + const char *filename, + FLAC__StreamEncoderProgressCallback progress_callback, + void *client_data, + FLAC__bool is_ogg +) +{ + FILE *file; + + FLAC__ASSERT(0 != encoder); + + /* + * To make sure that our file does not go unclosed after an error, we + * have to do the same entrance checks here that are later performed + * in FLAC__stream_encoder_init_FILE() before the FILE* is assigned. + */ + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; + + file = filename? flac_fopen(filename, "w+b") : stdout; + + if(file == 0) { + encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + + return init_FILE_internal_(encoder, file, progress_callback, client_data, is_ogg); +} + +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file( + FLAC__StreamEncoder *encoder, + const char *filename, + FLAC__StreamEncoderProgressCallback progress_callback, + void *client_data +) +{ + return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/false); +} + +FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file( + FLAC__StreamEncoder *encoder, + const char *filename, + FLAC__StreamEncoderProgressCallback progress_callback, + void *client_data +) +{ + return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/true); +} + +FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) +{ + FLAC__bool error = false; + + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + + if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED) + return true; + + if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) { + if(encoder->private_->current_sample_number != 0) { + const FLAC__bool is_fractional_block = encoder->protected_->blocksize != encoder->private_->current_sample_number; + encoder->protected_->blocksize = encoder->private_->current_sample_number; + if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true)) + error = true; + } + } + + if(encoder->protected_->do_md5) + FLAC__MD5Final(encoder->private_->streaminfo.data.stream_info.md5sum, &encoder->private_->md5context); + + if(!encoder->private_->is_being_deleted) { + if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK) { + if(encoder->private_->seek_callback) { +#if FLAC__HAS_OGG + if(encoder->private_->is_ogg) + update_ogg_metadata_(encoder); + else +#endif + update_metadata_(encoder); + + /* check if an error occurred while updating metadata */ + if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK) + error = true; + } + if(encoder->private_->metadata_callback) + encoder->private_->metadata_callback(encoder, &encoder->private_->streaminfo, encoder->private_->client_data); + } + + if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder && !FLAC__stream_decoder_finish(encoder->private_->verify.decoder)) { + if(!error) + encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA; + error = true; + } + } + + if(0 != encoder->private_->file) { + if(encoder->private_->file != stdout) + fclose(encoder->private_->file); + encoder->private_->file = 0; + } + +#if FLAC__HAS_OGG + if(encoder->private_->is_ogg) + FLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect); +#endif + + free_(encoder); + set_defaults_(encoder); + + if(!error) + encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; + + return !error; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; +#if FLAC__HAS_OGG + /* can't check encoder->private_->is_ogg since that's not set until init time */ + FLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value); + return true; +#else + (void)value; + return false; +#endif +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; +#ifndef FLAC__MANDATORY_VERIFY_WHILE_ENCODING + encoder->protected_->verify = value; +#endif + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->streamable_subset = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->do_md5 = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->channels = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->bits_per_sample = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->sample_rate = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__bool ok = true; + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + if(value >= sizeof(compression_levels_)/sizeof(compression_levels_[0])) + value = sizeof(compression_levels_)/sizeof(compression_levels_[0]) - 1; + ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo); + ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo); +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#if 1 + ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization); +#else + /* equivalent to -A tukey(0.5) */ + encoder->protected_->num_apodizations = 1; + encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; + encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; +#endif +#endif + ok &= FLAC__stream_encoder_set_max_lpc_order (encoder, compression_levels_[value].max_lpc_order); + ok &= FLAC__stream_encoder_set_qlp_coeff_precision (encoder, compression_levels_[value].qlp_coeff_precision); + ok &= FLAC__stream_encoder_set_do_qlp_coeff_prec_search (encoder, compression_levels_[value].do_qlp_coeff_prec_search); + ok &= FLAC__stream_encoder_set_do_escape_coding (encoder, compression_levels_[value].do_escape_coding); + ok &= FLAC__stream_encoder_set_do_exhaustive_model_search (encoder, compression_levels_[value].do_exhaustive_model_search); + ok &= FLAC__stream_encoder_set_min_residual_partition_order(encoder, compression_levels_[value].min_residual_partition_order); + ok &= FLAC__stream_encoder_set_max_residual_partition_order(encoder, compression_levels_[value].max_residual_partition_order); + ok &= FLAC__stream_encoder_set_rice_parameter_search_dist (encoder, compression_levels_[value].rice_parameter_search_dist); + return ok; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->blocksize = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->do_mid_side_stereo = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->loose_mid_side_stereo = value; + return true; +} + +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != specification); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; +#ifdef FLAC__INTEGER_ONLY_LIBRARY + (void)specification; /* silently ignore since we haven't integerized; will always use a rectangular window */ +#else + encoder->protected_->num_apodizations = 0; + while(1) { + const char *s = strchr(specification, ';'); + const size_t n = s? (size_t)(s - specification) : strlen(specification); + if (n==8 && 0 == strncmp("bartlett" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT; + else if(n==13 && 0 == strncmp("bartlett_hann", specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT_HANN; + else if(n==8 && 0 == strncmp("blackman" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN; + else if(n==26 && 0 == strncmp("blackman_harris_4term_92db", specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE; + else if(n==6 && 0 == strncmp("connes" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_CONNES; + else if(n==7 && 0 == strncmp("flattop" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_FLATTOP; + else if(n>7 && 0 == strncmp("gauss(" , specification, 6)) { + FLAC__real stddev = (FLAC__real)strtod(specification+6, 0); + if (stddev > 0.0 && stddev <= 0.5) { + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.gauss.stddev = stddev; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_GAUSS; + } + } + else if(n==7 && 0 == strncmp("hamming" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HAMMING; + else if(n==4 && 0 == strncmp("hann" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HANN; + else if(n==13 && 0 == strncmp("kaiser_bessel", specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_KAISER_BESSEL; + else if(n==7 && 0 == strncmp("nuttall" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_NUTTALL; + else if(n==9 && 0 == strncmp("rectangle" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_RECTANGLE; + else if(n==8 && 0 == strncmp("triangle" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TRIANGLE; + else if(n>7 && 0 == strncmp("tukey(" , specification, 6)) { + FLAC__real p = (FLAC__real)strtod(specification+6, 0); + if (p >= 0.0 && p <= 1.0) { + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; + } + } + else if(n>15 && 0 == strncmp("partial_tukey(" , specification, 14)) { + FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+14, 0); + const char *si_1 = strchr(specification, '/'); + FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.1f; + FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f; + const char *si_2 = strchr((si_1?(si_1+1):specification), '/'); + FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f; + + if (tukey_parts <= 1) { + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; + }else if (encoder->protected_->num_apodizations + tukey_parts < 32){ + FLAC__int32 m; + for(m = 0; m < tukey_parts; m++){ + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PARTIAL_TUKEY; + } + } + } + else if(n>16 && 0 == strncmp("punchout_tukey(" , specification, 15)) { + FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+15, 0); + const char *si_1 = strchr(specification, '/'); + FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.2f; + FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f; + const char *si_2 = strchr((si_1?(si_1+1):specification), '/'); + FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f; + + if (tukey_parts <= 1) { + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; + }else if (encoder->protected_->num_apodizations + tukey_parts < 32){ + FLAC__int32 m; + for(m = 0; m < tukey_parts; m++){ + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PUNCHOUT_TUKEY; + } + } + } + else if(n==5 && 0 == strncmp("welch" , specification, n)) + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH; + if (encoder->protected_->num_apodizations == 32) + break; + if (s) + specification = s+1; + else + break; + } + if(encoder->protected_->num_apodizations == 0) { + encoder->protected_->num_apodizations = 1; + encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; + encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; + } +#endif + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->max_lpc_order = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->qlp_coeff_precision = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->do_qlp_coeff_prec_search = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; +#if 0 + /*@@@ deprecated: */ + encoder->protected_->do_escape_coding = value; +#else + (void)value; +#endif + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->do_exhaustive_model_search = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->min_residual_partition_order = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->max_residual_partition_order = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; +#if 0 + /*@@@ deprecated: */ + encoder->protected_->rice_parameter_search_dist = value; +#else + (void)value; +#endif + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + value = flac_min(value, (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN) - 1); + encoder->protected_->total_samples_estimate = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + if(0 == metadata) + num_blocks = 0; + if(0 == num_blocks) + metadata = 0; + /* realloc() does not do exactly what we want so... */ + if(encoder->protected_->metadata) { + free(encoder->protected_->metadata); + encoder->protected_->metadata = 0; + encoder->protected_->num_metadata_blocks = 0; + } + if(num_blocks) { + FLAC__StreamMetadata **m; + if(0 == (m = safe_malloc_mul_2op_p(sizeof(m[0]), /*times*/num_blocks))) + return false; + memcpy(m, metadata, sizeof(m[0]) * num_blocks); + encoder->protected_->metadata = m; + encoder->protected_->num_metadata_blocks = num_blocks; + } +#if FLAC__HAS_OGG + if(!FLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks)) + return false; +#endif + return true; +} + +/* + * These three functions are not static, but not publically exposed in + * include/FLAC/ either. They are used by the test suite. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->disable_constant_subframes = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->disable_fixed_subframes = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->disable_verbatim_subframes = value; + return true; +} + +FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->state; +} + +FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->verify) + return FLAC__stream_decoder_get_state(encoder->private_->verify.decoder); + else + return FLAC__STREAM_DECODER_UNINITIALIZED; +} + +FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) + return FLAC__StreamEncoderStateString[encoder->protected_->state]; + else + return FLAC__stream_decoder_get_resolved_state_string(encoder->private_->verify.decoder); +} + +FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(0 != absolute_sample) + *absolute_sample = encoder->private_->verify.error_stats.absolute_sample; + if(0 != frame_number) + *frame_number = encoder->private_->verify.error_stats.frame_number; + if(0 != channel) + *channel = encoder->private_->verify.error_stats.channel; + if(0 != sample) + *sample = encoder->private_->verify.error_stats.sample; + if(0 != expected) + *expected = encoder->private_->verify.error_stats.expected; + if(0 != got) + *got = encoder->private_->verify.error_stats.got; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->verify; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->streamable_subset; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->do_md5; +} + +FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->channels; +} + +FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->bits_per_sample; +} + +FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->sample_rate; +} + +FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->blocksize; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->do_mid_side_stereo; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->loose_mid_side_stereo; +} + +FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->max_lpc_order; +} + +FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->qlp_coeff_precision; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->do_qlp_coeff_prec_search; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->do_escape_coding; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->do_exhaustive_model_search; +} + +FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->min_residual_partition_order; +} + +FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->max_residual_partition_order; +} + +FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->rice_parameter_search_dist; +} + +FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->total_samples_estimate; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) +{ + unsigned i, j = 0, channel; + const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; + + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); + + do { + const unsigned n = flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j); + + if(encoder->protected_->verify) + append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n); + + for(channel = 0; channel < channels; channel++) { + if (buffer[channel] == NULL) { + return false; + } + memcpy(&encoder->private_->integer_signal[channel][encoder->private_->current_sample_number], &buffer[channel][j], sizeof(buffer[channel][0]) * n); + } + + if(encoder->protected_->do_mid_side_stereo) { + FLAC__ASSERT(channels == 2); + /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ + for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { + encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j]; + encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */ + } + } + else + j += n; + + encoder->private_->current_sample_number += n; + + /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ + if(encoder->private_->current_sample_number > blocksize) { + FLAC__ASSERT(encoder->private_->current_sample_number == blocksize+OVERREAD_); + FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ + if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false)) + return false; + /* move unprocessed overread samples to beginnings of arrays */ + for(channel = 0; channel < channels; channel++) + encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize]; + if(encoder->protected_->do_mid_side_stereo) { + encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize]; + encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize]; + } + encoder->private_->current_sample_number = 1; + } + } while(j < samples); + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) +{ + unsigned i, j, k, channel; + FLAC__int32 x, mid, side; + const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; + + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); + + j = k = 0; + /* + * we have several flavors of the same basic loop, optimized for + * different conditions: + */ + if(encoder->protected_->do_mid_side_stereo && channels == 2) { + /* + * stereo coding: unroll channel loop + */ + do { + if(encoder->protected_->verify) + append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); + + /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ + for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { + encoder->private_->integer_signal[0][i] = mid = side = buffer[k++]; + x = buffer[k++]; + encoder->private_->integer_signal[1][i] = x; + mid += x; + side -= x; + mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */ + encoder->private_->integer_signal_mid_side[1][i] = side; + encoder->private_->integer_signal_mid_side[0][i] = mid; + } + encoder->private_->current_sample_number = i; + /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ + if(i > blocksize) { + if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false)) + return false; + /* move unprocessed overread samples to beginnings of arrays */ + FLAC__ASSERT(i == blocksize+OVERREAD_); + FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ + encoder->private_->integer_signal[0][0] = encoder->private_->integer_signal[0][blocksize]; + encoder->private_->integer_signal[1][0] = encoder->private_->integer_signal[1][blocksize]; + encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize]; + encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize]; + encoder->private_->current_sample_number = 1; + } + } while(j < samples); + } + else { + /* + * independent channel coding: buffer each channel in inner loop + */ + do { + if(encoder->protected_->verify) + append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); + + /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ + for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { + for(channel = 0; channel < channels; channel++) + encoder->private_->integer_signal[channel][i] = buffer[k++]; + } + encoder->private_->current_sample_number = i; + /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ + if(i > blocksize) { + if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false)) + return false; + /* move unprocessed overread samples to beginnings of arrays */ + FLAC__ASSERT(i == blocksize+OVERREAD_); + FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ + for(channel = 0; channel < channels; channel++) + encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize]; + encoder->private_->current_sample_number = 1; + } + } while(j < samples); + } + + return true; +} + +/*********************************************************************** + * + * Private class methods + * + ***********************************************************************/ + +void set_defaults_(FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + +#ifdef FLAC__MANDATORY_VERIFY_WHILE_ENCODING + encoder->protected_->verify = true; +#else + encoder->protected_->verify = false; +#endif + encoder->protected_->streamable_subset = true; + encoder->protected_->do_md5 = true; + encoder->protected_->do_mid_side_stereo = false; + encoder->protected_->loose_mid_side_stereo = false; + encoder->protected_->channels = 2; + encoder->protected_->bits_per_sample = 16; + encoder->protected_->sample_rate = 44100; + encoder->protected_->blocksize = 0; +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->protected_->num_apodizations = 1; + encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; + encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; +#endif + encoder->protected_->max_lpc_order = 0; + encoder->protected_->qlp_coeff_precision = 0; + encoder->protected_->do_qlp_coeff_prec_search = false; + encoder->protected_->do_exhaustive_model_search = false; + encoder->protected_->do_escape_coding = false; + encoder->protected_->min_residual_partition_order = 0; + encoder->protected_->max_residual_partition_order = 0; + encoder->protected_->rice_parameter_search_dist = 0; + encoder->protected_->total_samples_estimate = 0; + encoder->protected_->metadata = 0; + encoder->protected_->num_metadata_blocks = 0; + + encoder->private_->seek_table = 0; + encoder->private_->disable_constant_subframes = false; + encoder->private_->disable_fixed_subframes = false; + encoder->private_->disable_verbatim_subframes = false; + encoder->private_->is_ogg = false; + encoder->private_->read_callback = 0; + encoder->private_->write_callback = 0; + encoder->private_->seek_callback = 0; + encoder->private_->tell_callback = 0; + encoder->private_->metadata_callback = 0; + encoder->private_->progress_callback = 0; + encoder->private_->client_data = 0; + +#if FLAC__HAS_OGG + FLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect); +#endif + + FLAC__stream_encoder_set_compression_level(encoder, 5); +} + +void free_(FLAC__StreamEncoder *encoder) +{ + unsigned i, channel; + + FLAC__ASSERT(0 != encoder); + if(encoder->protected_->metadata) { + free(encoder->protected_->metadata); + encoder->protected_->metadata = 0; + encoder->protected_->num_metadata_blocks = 0; + } + for(i = 0; i < encoder->protected_->channels; i++) { + if(0 != encoder->private_->integer_signal_unaligned[i]) { + free(encoder->private_->integer_signal_unaligned[i]); + encoder->private_->integer_signal_unaligned[i] = 0; + } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + if(0 != encoder->private_->real_signal_unaligned[i]) { + free(encoder->private_->real_signal_unaligned[i]); + encoder->private_->real_signal_unaligned[i] = 0; + } +#endif + } + for(i = 0; i < 2; i++) { + if(0 != encoder->private_->integer_signal_mid_side_unaligned[i]) { + free(encoder->private_->integer_signal_mid_side_unaligned[i]); + encoder->private_->integer_signal_mid_side_unaligned[i] = 0; + } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + if(0 != encoder->private_->real_signal_mid_side_unaligned[i]) { + free(encoder->private_->real_signal_mid_side_unaligned[i]); + encoder->private_->real_signal_mid_side_unaligned[i] = 0; + } +#endif + } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + for(i = 0; i < encoder->protected_->num_apodizations; i++) { + if(0 != encoder->private_->window_unaligned[i]) { + free(encoder->private_->window_unaligned[i]); + encoder->private_->window_unaligned[i] = 0; + } + } + if(0 != encoder->private_->windowed_signal_unaligned) { + free(encoder->private_->windowed_signal_unaligned); + encoder->private_->windowed_signal_unaligned = 0; + } +#endif + for(channel = 0; channel < encoder->protected_->channels; channel++) { + for(i = 0; i < 2; i++) { + if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) { + free(encoder->private_->residual_workspace_unaligned[channel][i]); + encoder->private_->residual_workspace_unaligned[channel][i] = 0; + } + } + } + for(channel = 0; channel < 2; channel++) { + for(i = 0; i < 2; i++) { + if(0 != encoder->private_->residual_workspace_mid_side_unaligned[channel][i]) { + free(encoder->private_->residual_workspace_mid_side_unaligned[channel][i]); + encoder->private_->residual_workspace_mid_side_unaligned[channel][i] = 0; + } + } + } + if(0 != encoder->private_->abs_residual_partition_sums_unaligned) { + free(encoder->private_->abs_residual_partition_sums_unaligned); + encoder->private_->abs_residual_partition_sums_unaligned = 0; + } + if(0 != encoder->private_->raw_bits_per_partition_unaligned) { + free(encoder->private_->raw_bits_per_partition_unaligned); + encoder->private_->raw_bits_per_partition_unaligned = 0; + } + if(encoder->protected_->verify) { + for(i = 0; i < encoder->protected_->channels; i++) { + if(0 != encoder->private_->verify.input_fifo.data[i]) { + free(encoder->private_->verify.input_fifo.data[i]); + encoder->private_->verify.input_fifo.data[i] = 0; + } + } + } + FLAC__bitwriter_free(encoder->private_->frame); +} + +FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize) +{ + FLAC__bool ok; + unsigned i, channel; + + FLAC__ASSERT(new_blocksize > 0); + FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); + FLAC__ASSERT(encoder->private_->current_sample_number == 0); + + /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */ + if(new_blocksize <= encoder->private_->input_capacity) + return true; + + ok = true; + + /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2() + * require that the input arrays (in our case the integer signals) + * have a buffer of up to 3 zeroes in front (at negative indices) for + * alignment purposes; we use 4 in front to keep the data well-aligned. + */ + + for(i = 0; ok && i < encoder->protected_->channels; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]); + memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4); + encoder->private_->integer_signal[i] += 4; +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#if 0 /* @@@ currently unused */ + if(encoder->protected_->max_lpc_order > 0) + ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]); +#endif +#endif + } + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]); + memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4); + encoder->private_->integer_signal_mid_side[i] += 4; +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#if 0 /* @@@ currently unused */ + if(encoder->protected_->max_lpc_order > 0) + ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]); +#endif +#endif + } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + if(ok && encoder->protected_->max_lpc_order > 0) { + for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) + ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]); + ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->windowed_signal_unaligned, &encoder->private_->windowed_signal); + } +#endif + for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]); + } + } + for(channel = 0; ok && channel < 2; channel++) { + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]); + } + } + /* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */ + /*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */ + ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums); + if(encoder->protected_->do_escape_coding) + ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition); + + /* now adjust the windows if the blocksize has changed */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY + if(ok && new_blocksize != encoder->private_->input_capacity && encoder->protected_->max_lpc_order > 0) { + for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) { + switch(encoder->protected_->apodizations[i].type) { + case FLAC__APODIZATION_BARTLETT: + FLAC__window_bartlett(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_BARTLETT_HANN: + FLAC__window_bartlett_hann(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_BLACKMAN: + FLAC__window_blackman(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE: + FLAC__window_blackman_harris_4term_92db_sidelobe(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_CONNES: + FLAC__window_connes(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_FLATTOP: + FLAC__window_flattop(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_GAUSS: + FLAC__window_gauss(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.gauss.stddev); + break; + case FLAC__APODIZATION_HAMMING: + FLAC__window_hamming(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_HANN: + FLAC__window_hann(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_KAISER_BESSEL: + FLAC__window_kaiser_bessel(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_NUTTALL: + FLAC__window_nuttall(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_RECTANGLE: + FLAC__window_rectangle(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_TRIANGLE: + FLAC__window_triangle(encoder->private_->window[i], new_blocksize); + break; + case FLAC__APODIZATION_TUKEY: + FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); + break; + case FLAC__APODIZATION_PARTIAL_TUKEY: + FLAC__window_partial_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); + break; + case FLAC__APODIZATION_PUNCHOUT_TUKEY: + FLAC__window_punchout_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); + break; + case FLAC__APODIZATION_WELCH: + FLAC__window_welch(encoder->private_->window[i], new_blocksize); + break; + default: + FLAC__ASSERT(0); + /* double protection */ + FLAC__window_hann(encoder->private_->window[i], new_blocksize); + break; + } + } + } +#endif + + if(ok) + encoder->private_->input_capacity = new_blocksize; + else + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + + return ok; +} + +FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block) +{ + const FLAC__byte *buffer; + size_t bytes; + + FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->frame)); + + if(!FLAC__bitwriter_get_buffer(encoder->private_->frame, &buffer, &bytes)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + if(encoder->protected_->verify) { + encoder->private_->verify.output.data = buffer; + encoder->private_->verify.output.bytes = bytes; + if(encoder->private_->verify.state_hint == ENCODER_IN_MAGIC) { + encoder->private_->verify.needs_magic_hack = true; + } + else { + if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)) { + FLAC__bitwriter_release_buffer(encoder->private_->frame); + FLAC__bitwriter_clear(encoder->private_->frame); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) + encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; + return false; + } + } + } + + if(write_frame_(encoder, buffer, bytes, samples, is_last_block) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + FLAC__bitwriter_release_buffer(encoder->private_->frame); + FLAC__bitwriter_clear(encoder->private_->frame); + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } + + FLAC__bitwriter_release_buffer(encoder->private_->frame); + FLAC__bitwriter_clear(encoder->private_->frame); + + if(samples > 0) { + encoder->private_->streaminfo.data.stream_info.min_framesize = flac_min(bytes, encoder->private_->streaminfo.data.stream_info.min_framesize); + encoder->private_->streaminfo.data.stream_info.max_framesize = flac_max(bytes, encoder->private_->streaminfo.data.stream_info.max_framesize); + } + + return true; +} + +FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block) +{ + FLAC__StreamEncoderWriteStatus status; + FLAC__uint64 output_position = 0; + +#if FLAC__HAS_OGG == 0 + (void)is_last_block; +#endif + + /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ + if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; + } + + /* + * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets. + */ + if(samples == 0) { + FLAC__MetadataType type = (buffer[0] & 0x7f); + if(type == FLAC__METADATA_TYPE_STREAMINFO) + encoder->protected_->streaminfo_offset = output_position; + else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0) + encoder->protected_->seektable_offset = output_position; + } + + /* + * Mark the current seek point if hit (if audio_offset == 0 that + * means we're still writing metadata and haven't hit the first + * frame yet) + */ + if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) { + const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder); + const FLAC__uint64 frame_first_sample = encoder->private_->samples_written; + const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1; + FLAC__uint64 test_sample; + unsigned i; + for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) { + test_sample = encoder->private_->seek_table->points[i].sample_number; + if(test_sample > frame_last_sample) { + break; + } + else if(test_sample >= frame_first_sample) { + encoder->private_->seek_table->points[i].sample_number = frame_first_sample; + encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset; + encoder->private_->seek_table->points[i].frame_samples = blocksize; + encoder->private_->first_seekpoint_to_check++; + /* DO NOT: "break;" and here's why: + * The seektable template may contain more than one target + * sample for any given frame; we will keep looping, generating + * duplicate seekpoints for them, and we'll clean it up later, + * just before writing the seektable back to the metadata. + */ + } + else { + encoder->private_->first_seekpoint_to_check++; + } + } + } + +#if FLAC__HAS_OGG + if(encoder->private_->is_ogg) { + status = FLAC__ogg_encoder_aspect_write_callback_wrapper( + &encoder->protected_->ogg_encoder_aspect, + buffer, + bytes, + samples, + encoder->private_->current_frame_number, + is_last_block, + (FLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, + encoder, + encoder->private_->client_data + ); + } + else +#endif + status = encoder->private_->write_callback(encoder, buffer, bytes, samples, encoder->private_->current_frame_number, encoder->private_->client_data); + + if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->private_->bytes_written += bytes; + encoder->private_->samples_written += samples; + /* we keep a high watermark on the number of frames written because + * when the encoder goes back to write metadata, 'current_frame' + * will drop back to 0. + */ + encoder->private_->frames_written = flac_max(encoder->private_->frames_written, encoder->private_->current_frame_number+1); + } + else + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + + return status; +} + +/* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */ +void update_metadata_(const FLAC__StreamEncoder *encoder) +{ + FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; + const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; + const FLAC__uint64 samples = metadata->data.stream_info.total_samples; + const unsigned min_framesize = metadata->data.stream_info.min_framesize; + const unsigned max_framesize = metadata->data.stream_info.max_framesize; + const unsigned bps = metadata->data.stream_info.bits_per_sample; + FLAC__StreamEncoderSeekStatus seek_status; + + FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); + + /* All this is based on intimate knowledge of the stream header + * layout, but a change to the header format that would break this + * would also break all streams encoded in the previous format. + */ + + /* + * Write MD5 signature + */ + { + const unsigned md5_offset = + FLAC__STREAM_METADATA_HEADER_LENGTH + + ( + FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + + FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN + ) / 8; + + if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { + if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + } + + /* + * Write total samples + */ + { + const unsigned total_samples_byte_offset = + FLAC__STREAM_METADATA_HEADER_LENGTH + + ( + FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + + FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + - 4 + ) / 8; + + b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F); + b[1] = (FLAC__byte)((samples >> 24) & 0xFF); + b[2] = (FLAC__byte)((samples >> 16) & 0xFF); + b[3] = (FLAC__byte)((samples >> 8) & 0xFF); + b[4] = (FLAC__byte)(samples & 0xFF); + if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { + if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + } + + /* + * Write min/max framesize + */ + { + const unsigned min_framesize_offset = + FLAC__STREAM_METADATA_HEADER_LENGTH + + ( + FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + ) / 8; + + b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF); + b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF); + b[2] = (FLAC__byte)(min_framesize & 0xFF); + b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF); + b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF); + b[5] = (FLAC__byte)(max_framesize & 0xFF); + if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { + if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + } + + /* + * Write seektable + */ + if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) { + unsigned i; + + FLAC__format_seektable_sort(encoder->private_->seek_table); + + FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table)); + + if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { + if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + + for(i = 0; i < encoder->private_->seek_table->num_points; i++) { + FLAC__uint64 xx; + unsigned x; + xx = encoder->private_->seek_table->points[i].sample_number; + b[7] = (FLAC__byte)xx; xx >>= 8; + b[6] = (FLAC__byte)xx; xx >>= 8; + b[5] = (FLAC__byte)xx; xx >>= 8; + b[4] = (FLAC__byte)xx; xx >>= 8; + b[3] = (FLAC__byte)xx; xx >>= 8; + b[2] = (FLAC__byte)xx; xx >>= 8; + b[1] = (FLAC__byte)xx; xx >>= 8; + b[0] = (FLAC__byte)xx; xx >>= 8; + xx = encoder->private_->seek_table->points[i].stream_offset; + b[15] = (FLAC__byte)xx; xx >>= 8; + b[14] = (FLAC__byte)xx; xx >>= 8; + b[13] = (FLAC__byte)xx; xx >>= 8; + b[12] = (FLAC__byte)xx; xx >>= 8; + b[11] = (FLAC__byte)xx; xx >>= 8; + b[10] = (FLAC__byte)xx; xx >>= 8; + b[9] = (FLAC__byte)xx; xx >>= 8; + b[8] = (FLAC__byte)xx; xx >>= 8; + x = encoder->private_->seek_table->points[i].frame_samples; + b[17] = (FLAC__byte)x; x >>= 8; + b[16] = (FLAC__byte)x; x >>= 8; + if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return; + } + } + } +} + +#if FLAC__HAS_OGG +/* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */ +void update_ogg_metadata_(FLAC__StreamEncoder *encoder) +{ + /* the # of bytes in the 1st packet that precede the STREAMINFO */ + static const unsigned FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH = + FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + + FLAC__OGG_MAPPING_MAGIC_LENGTH + + FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + + FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + + FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + + FLAC__STREAM_SYNC_LENGTH + ; + FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; + const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; + const FLAC__uint64 samples = metadata->data.stream_info.total_samples; + const unsigned min_framesize = metadata->data.stream_info.min_framesize; + const unsigned max_framesize = metadata->data.stream_info.max_framesize; + ogg_page page; + + FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); + FLAC__ASSERT(0 != encoder->private_->seek_callback); + + /* Pre-check that client supports seeking, since we don't want the + * ogg_helper code to ever have to deal with this condition. + */ + if(encoder->private_->seek_callback(encoder, 0, encoder->private_->client_data) == FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED) + return; + + /* All this is based on intimate knowledge of the stream header + * layout, but a change to the header format that would break this + * would also break all streams encoded in the previous format. + */ + + /** + ** Write STREAMINFO stats + **/ + simple_ogg_page__init(&page); + if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) { + simple_ogg_page__clear(&page); + return; /* state already set */ + } + + /* + * Write MD5 signature + */ + { + const unsigned md5_offset = + FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH + + FLAC__STREAM_METADATA_HEADER_LENGTH + + ( + FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + + FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN + ) / 8; + + if(md5_offset + 16 > (unsigned)page.body_len) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + simple_ogg_page__clear(&page); + return; + } + memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16); + } + + /* + * Write total samples + */ + { + const unsigned total_samples_byte_offset = + FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH + + FLAC__STREAM_METADATA_HEADER_LENGTH + + ( + FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + + FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + - 4 + ) / 8; + + if(total_samples_byte_offset + 5 > (unsigned)page.body_len) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + simple_ogg_page__clear(&page); + return; + } + b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0; + b[0] |= (FLAC__byte)((samples >> 32) & 0x0F); + b[1] = (FLAC__byte)((samples >> 24) & 0xFF); + b[2] = (FLAC__byte)((samples >> 16) & 0xFF); + b[3] = (FLAC__byte)((samples >> 8) & 0xFF); + b[4] = (FLAC__byte)(samples & 0xFF); + memcpy(page.body + total_samples_byte_offset, b, 5); + } + + /* + * Write min/max framesize + */ + { + const unsigned min_framesize_offset = + FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH + + FLAC__STREAM_METADATA_HEADER_LENGTH + + ( + FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + + FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + ) / 8; + + if(min_framesize_offset + 6 > (unsigned)page.body_len) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + simple_ogg_page__clear(&page); + return; + } + b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF); + b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF); + b[2] = (FLAC__byte)(min_framesize & 0xFF); + b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF); + b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF); + b[5] = (FLAC__byte)(max_framesize & 0xFF); + memcpy(page.body + min_framesize_offset, b, 6); + } + if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) { + simple_ogg_page__clear(&page); + return; /* state already set */ + } + simple_ogg_page__clear(&page); + + /* + * Write seektable + */ + if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) { + unsigned i; + FLAC__byte *p; + + FLAC__format_seektable_sort(encoder->private_->seek_table); + + FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table)); + + simple_ogg_page__init(&page); + if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) { + simple_ogg_page__clear(&page); + return; /* state already set */ + } + + if((FLAC__STREAM_METADATA_HEADER_LENGTH + 18*encoder->private_->seek_table->num_points) != (unsigned)page.body_len) { + encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; + simple_ogg_page__clear(&page); + return; + } + + for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) { + FLAC__uint64 xx; + unsigned x; + xx = encoder->private_->seek_table->points[i].sample_number; + b[7] = (FLAC__byte)xx; xx >>= 8; + b[6] = (FLAC__byte)xx; xx >>= 8; + b[5] = (FLAC__byte)xx; xx >>= 8; + b[4] = (FLAC__byte)xx; xx >>= 8; + b[3] = (FLAC__byte)xx; xx >>= 8; + b[2] = (FLAC__byte)xx; xx >>= 8; + b[1] = (FLAC__byte)xx; xx >>= 8; + b[0] = (FLAC__byte)xx; xx >>= 8; + xx = encoder->private_->seek_table->points[i].stream_offset; + b[15] = (FLAC__byte)xx; xx >>= 8; + b[14] = (FLAC__byte)xx; xx >>= 8; + b[13] = (FLAC__byte)xx; xx >>= 8; + b[12] = (FLAC__byte)xx; xx >>= 8; + b[11] = (FLAC__byte)xx; xx >>= 8; + b[10] = (FLAC__byte)xx; xx >>= 8; + b[9] = (FLAC__byte)xx; xx >>= 8; + b[8] = (FLAC__byte)xx; xx >>= 8; + x = encoder->private_->seek_table->points[i].frame_samples; + b[17] = (FLAC__byte)x; x >>= 8; + b[16] = (FLAC__byte)x; x >>= 8; + memcpy(p, b, 18); + } + + if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) { + simple_ogg_page__clear(&page); + return; /* state already set */ + } + simple_ogg_page__clear(&page); + } +} +#endif + +FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block) +{ + FLAC__uint16 crc; + FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); + + /* + * Accumulate raw signal to the MD5 signature + */ + if(encoder->protected_->do_md5 && !FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + /* + * Process the frame header and subframes into the frame bitbuffer + */ + if(!process_subframes_(encoder, is_fractional_block)) { + /* the above function sets the state for us in case of an error */ + return false; + } + + /* + * Zero-pad the frame to a byte_boundary + */ + if(!FLAC__bitwriter_zero_pad_to_byte_boundary(encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + /* + * CRC-16 the whole thing + */ + FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->frame)); + if( + !FLAC__bitwriter_get_write_crc16(encoder->private_->frame, &crc) || + !FLAC__bitwriter_write_raw_uint32(encoder->private_->frame, crc, FLAC__FRAME_FOOTER_CRC_LEN) + ) { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + /* + * Write it + */ + if(!write_bitbuffer_(encoder, encoder->protected_->blocksize, is_last_block)) { + /* the above function sets the state for us in case of an error */ + return false; + } + + /* + * Get ready for the next frame + */ + encoder->private_->current_sample_number = 0; + encoder->private_->current_frame_number++; + encoder->private_->streaminfo.data.stream_info.total_samples += (FLAC__uint64)encoder->protected_->blocksize; + + return true; +} + +FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block) +{ + FLAC__FrameHeader frame_header; + unsigned channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order; + FLAC__bool do_independent, do_mid_side; + + /* + * Calculate the min,max Rice partition orders + */ + if(is_fractional_block) { + max_partition_order = 0; + } + else { + max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); + max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order); + } + min_partition_order = flac_min(min_partition_order, max_partition_order); + + /* + * Setup the frame + */ + frame_header.blocksize = encoder->protected_->blocksize; + frame_header.sample_rate = encoder->protected_->sample_rate; + frame_header.channels = encoder->protected_->channels; + frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; /* the default unless the encoder determines otherwise */ + frame_header.bits_per_sample = encoder->protected_->bits_per_sample; + frame_header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER; + frame_header.number.frame_number = encoder->private_->current_frame_number; + + /* + * Figure out what channel assignments to try + */ + if(encoder->protected_->do_mid_side_stereo) { + if(encoder->protected_->loose_mid_side_stereo) { + if(encoder->private_->loose_mid_side_stereo_frame_count == 0) { + do_independent = true; + do_mid_side = true; + } + else { + do_independent = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT); + do_mid_side = !do_independent; + } + } + else { + do_independent = true; + do_mid_side = true; + } + } + else { + do_independent = true; + do_mid_side = false; + } + + FLAC__ASSERT(do_independent || do_mid_side); + + /* + * Check for wasted bits; set effective bps for each subframe + */ + if(do_independent) { + for(channel = 0; channel < encoder->protected_->channels; channel++) { + unsigned w = get_wasted_bits_(encoder->private_->integer_signal[channel], encoder->protected_->blocksize); + if (w > encoder->protected_->bits_per_sample) { + w = encoder->protected_->bits_per_sample; + } + encoder->private_->subframe_workspace[channel][0].wasted_bits = encoder->private_->subframe_workspace[channel][1].wasted_bits = w; + encoder->private_->subframe_bps[channel] = encoder->protected_->bits_per_sample - w; + } + } + if(do_mid_side) { + FLAC__ASSERT(encoder->protected_->channels == 2); + for(channel = 0; channel < 2; channel++) { + unsigned w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); + if (w > encoder->protected_->bits_per_sample) { + w = encoder->protected_->bits_per_sample; + } + encoder->private_->subframe_workspace_mid_side[channel][0].wasted_bits = encoder->private_->subframe_workspace_mid_side[channel][1].wasted_bits = w; + encoder->private_->subframe_bps_mid_side[channel] = encoder->protected_->bits_per_sample - w + (channel==0? 0:1); + } + } + + /* + * First do a normal encoding pass of each independent channel + */ + if(do_independent) { + for(channel = 0; channel < encoder->protected_->channels; channel++) { + if(! + process_subframe_( + encoder, + min_partition_order, + max_partition_order, + &frame_header, + encoder->private_->subframe_bps[channel], + encoder->private_->integer_signal[channel], + encoder->private_->subframe_workspace_ptr[channel], + encoder->private_->partitioned_rice_contents_workspace_ptr[channel], + encoder->private_->residual_workspace[channel], + encoder->private_->best_subframe+channel, + encoder->private_->best_subframe_bits+channel + ) + ) + return false; + } + } + + /* + * Now do mid and side channels if requested + */ + if(do_mid_side) { + FLAC__ASSERT(encoder->protected_->channels == 2); + + for(channel = 0; channel < 2; channel++) { + if(! + process_subframe_( + encoder, + min_partition_order, + max_partition_order, + &frame_header, + encoder->private_->subframe_bps_mid_side[channel], + encoder->private_->integer_signal_mid_side[channel], + encoder->private_->subframe_workspace_ptr_mid_side[channel], + encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel], + encoder->private_->residual_workspace_mid_side[channel], + encoder->private_->best_subframe_mid_side+channel, + encoder->private_->best_subframe_bits_mid_side+channel + ) + ) + return false; + } + } + + /* + * Compose the frame bitbuffer + */ + if(do_mid_side) { + unsigned left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */ + FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */ + FLAC__ChannelAssignment channel_assignment; + + FLAC__ASSERT(encoder->protected_->channels == 2); + + if(encoder->protected_->loose_mid_side_stereo && encoder->private_->loose_mid_side_stereo_frame_count > 0) { + channel_assignment = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT? FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT : FLAC__CHANNEL_ASSIGNMENT_MID_SIDE); + } + else { + unsigned bits[4]; /* WATCHOUT - indexed by FLAC__ChannelAssignment */ + unsigned min_bits; + int ca; + + FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT == 0); + FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE == 1); + FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE == 2); + FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_MID_SIDE == 3); + FLAC__ASSERT(do_independent && do_mid_side); + + /* We have to figure out which channel assignent results in the smallest frame */ + bits[FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT] = encoder->private_->best_subframe_bits [0] + encoder->private_->best_subframe_bits [1]; + bits[FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE ] = encoder->private_->best_subframe_bits [0] + encoder->private_->best_subframe_bits_mid_side[1]; + bits[FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ] = encoder->private_->best_subframe_bits [1] + encoder->private_->best_subframe_bits_mid_side[1]; + bits[FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ] = encoder->private_->best_subframe_bits_mid_side[0] + encoder->private_->best_subframe_bits_mid_side[1]; + + channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; + min_bits = bits[channel_assignment]; + for(ca = 1; ca <= 3; ca++) { + if(bits[ca] < min_bits) { + min_bits = bits[ca]; + channel_assignment = (FLAC__ChannelAssignment)ca; + } + } + } + + frame_header.channel_assignment = channel_assignment; + + if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return false; + } + + switch(channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]]; + right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]]; + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]]; + right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]]; + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + left_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]]; + right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]]; + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + left_subframe = &encoder->private_->subframe_workspace_mid_side[0][encoder->private_->best_subframe_mid_side[0]]; + right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]]; + break; + default: + FLAC__ASSERT(0); + } + + switch(channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + left_bps = encoder->private_->subframe_bps [0]; + right_bps = encoder->private_->subframe_bps [1]; + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + left_bps = encoder->private_->subframe_bps [0]; + right_bps = encoder->private_->subframe_bps_mid_side[1]; + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + left_bps = encoder->private_->subframe_bps_mid_side[1]; + right_bps = encoder->private_->subframe_bps [1]; + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + left_bps = encoder->private_->subframe_bps_mid_side[0]; + right_bps = encoder->private_->subframe_bps_mid_side[1]; + break; + default: + FLAC__ASSERT(0); + } + + /* note that encoder_add_subframe_ sets the state for us in case of an error */ + if(!add_subframe_(encoder, frame_header.blocksize, left_bps , left_subframe , encoder->private_->frame)) + return false; + if(!add_subframe_(encoder, frame_header.blocksize, right_bps, right_subframe, encoder->private_->frame)) + return false; + } + else { + if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return false; + } + + for(channel = 0; channel < encoder->protected_->channels; channel++) { + if(!add_subframe_(encoder, frame_header.blocksize, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) { + /* the above function sets the state for us in case of an error */ + return false; + } + } + } + + if(encoder->protected_->loose_mid_side_stereo) { + encoder->private_->loose_mid_side_stereo_frame_count++; + if(encoder->private_->loose_mid_side_stereo_frame_count >= encoder->private_->loose_mid_side_stereo_frames) + encoder->private_->loose_mid_side_stereo_frame_count = 0; + } + + encoder->private_->last_channel_assignment = frame_header.channel_assignment; + + return true; +} + +FLAC__bool process_subframe_( + FLAC__StreamEncoder *encoder, + unsigned min_partition_order, + unsigned max_partition_order, + const FLAC__FrameHeader *frame_header, + unsigned subframe_bps, + const FLAC__int32 integer_signal[], + FLAC__Subframe *subframe[2], + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], + FLAC__int32 *residual[2], + unsigned *best_subframe, + unsigned *best_bits +) +{ +#ifndef FLAC__INTEGER_ONLY_LIBRARY + float fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; +#else + FLAC__fixedpoint fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; +#endif +#ifndef FLAC__INTEGER_ONLY_LIBRARY + double lpc_residual_bits_per_sample; + FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm and x86 intrinsic routines need all the space */ + double lpc_error[FLAC__MAX_LPC_ORDER]; + unsigned min_lpc_order, max_lpc_order, lpc_order; + unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; +#endif + unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order; + unsigned rice_parameter; + unsigned _candidate_bits, _best_bits; + unsigned _best_subframe; + /* only use RICE2 partitions if stream bps > 16 */ + const unsigned rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + + FLAC__ASSERT(frame_header->blocksize > 0); + + /* verbatim subframe is the baseline against which we measure other compressed subframes */ + _best_subframe = 0; + if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) + _best_bits = UINT_MAX; + else + _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); + + if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) { + unsigned signal_is_constant = false; + if(subframe_bps + 4 + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)|1) <= 32) + guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + else + guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + /* check for constant subframe */ + if( + !encoder->private_->disable_constant_subframes && +#ifndef FLAC__INTEGER_ONLY_LIBRARY + fixed_residual_bits_per_sample[1] == 0.0 +#else + fixed_residual_bits_per_sample[1] == FLAC__FP_ZERO +#endif + ) { + /* the above means it's possible all samples are the same value; now double-check it: */ + unsigned i; + signal_is_constant = true; + for(i = 1; i < frame_header->blocksize; i++) { + if(integer_signal[0] != integer_signal[i]) { + signal_is_constant = false; + break; + } + } + } + if(signal_is_constant) { + _candidate_bits = evaluate_constant_subframe_(encoder, integer_signal[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]); + if(_candidate_bits < _best_bits) { + _best_subframe = !_best_subframe; + _best_bits = _candidate_bits; + } + } + else { + if(!encoder->private_->disable_fixed_subframes || (encoder->protected_->max_lpc_order == 0 && _best_bits == UINT_MAX)) { + /* encode fixed */ + if(encoder->protected_->do_exhaustive_model_search) { + min_fixed_order = 0; + max_fixed_order = FLAC__MAX_FIXED_ORDER; + } + else { + min_fixed_order = max_fixed_order = guess_fixed_order; + } + if(max_fixed_order >= frame_header->blocksize) + max_fixed_order = frame_header->blocksize - 1; + for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) { +#ifndef FLAC__INTEGER_ONLY_LIBRARY + if(fixed_residual_bits_per_sample[fixed_order] >= (float)subframe_bps) + continue; /* don't even try */ + rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */ +#else + if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps) + continue; /* don't even try */ + rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */ +#endif + rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ + if(rice_parameter >= rice_parameter_limit) { +#ifdef DEBUG_VERBOSE + fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1); +#endif + rice_parameter = rice_parameter_limit - 1; + } + _candidate_bits = + evaluate_fixed_subframe_( + encoder, + integer_signal, + residual[!_best_subframe], + encoder->private_->abs_residual_partition_sums, + encoder->private_->raw_bits_per_partition, + frame_header->blocksize, + subframe_bps, + fixed_order, + rice_parameter, + rice_parameter_limit, + min_partition_order, + max_partition_order, + encoder->protected_->do_escape_coding, + encoder->protected_->rice_parameter_search_dist, + subframe[!_best_subframe], + partitioned_rice_contents[!_best_subframe] + ); + if(_candidate_bits < _best_bits) { + _best_subframe = !_best_subframe; + _best_bits = _candidate_bits; + } + } + } + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + /* encode lpc */ + if(encoder->protected_->max_lpc_order > 0) { + if(encoder->protected_->max_lpc_order >= frame_header->blocksize) + max_lpc_order = frame_header->blocksize-1; + else + max_lpc_order = encoder->protected_->max_lpc_order; + if(max_lpc_order > 0) { + unsigned a; + for (a = 0; a < encoder->protected_->num_apodizations; a++) { + FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize); + encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc); + /* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */ + if(autoc[0] != 0.0) { + FLAC__lpc_compute_lp_coefficients(autoc, &max_lpc_order, encoder->private_->lp_coeff, lpc_error); + if(encoder->protected_->do_exhaustive_model_search) { + min_lpc_order = 1; + } + else { + const unsigned guess_lpc_order = + FLAC__lpc_compute_best_order( + lpc_error, + max_lpc_order, + frame_header->blocksize, + subframe_bps + ( + encoder->protected_->do_qlp_coeff_prec_search? + FLAC__MIN_QLP_COEFF_PRECISION : /* have to guess; use the min possible size to avoid accidentally favoring lower orders */ + encoder->protected_->qlp_coeff_precision + ) + ); + min_lpc_order = max_lpc_order = guess_lpc_order; + } + if(max_lpc_order >= frame_header->blocksize) + max_lpc_order = frame_header->blocksize - 1; + for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) { + lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order); + if(lpc_residual_bits_per_sample >= (double)subframe_bps) + continue; /* don't even try */ + rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */ + rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ + if(rice_parameter >= rice_parameter_limit) { +#ifdef DEBUG_VERBOSE + fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1); +#endif + rice_parameter = rice_parameter_limit - 1; + } + if(encoder->protected_->do_qlp_coeff_prec_search) { + min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; + /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */ + if(subframe_bps <= 17) { + max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION); + max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); + } + else + max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; + } + else { + min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision; + } + for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) { + _candidate_bits = + evaluate_lpc_subframe_( + encoder, + integer_signal, + residual[!_best_subframe], + encoder->private_->abs_residual_partition_sums, + encoder->private_->raw_bits_per_partition, + encoder->private_->lp_coeff[lpc_order-1], + frame_header->blocksize, + subframe_bps, + lpc_order, + qlp_coeff_precision, + rice_parameter, + rice_parameter_limit, + min_partition_order, + max_partition_order, + encoder->protected_->do_escape_coding, + encoder->protected_->rice_parameter_search_dist, + subframe[!_best_subframe], + partitioned_rice_contents[!_best_subframe] + ); + if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */ + if(_candidate_bits < _best_bits) { + _best_subframe = !_best_subframe; + _best_bits = _candidate_bits; + } + } + } + } + } + } + } + } +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + } + } + + /* under rare circumstances this can happen when all but lpc subframe types are disabled: */ + if(_best_bits == UINT_MAX) { + FLAC__ASSERT(_best_subframe == 0); + _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); + } + + *best_subframe = _best_subframe; + *best_bits = _best_bits; + + return true; +} + +FLAC__bool add_subframe_( + FLAC__StreamEncoder *encoder, + unsigned blocksize, + unsigned subframe_bps, + const FLAC__Subframe *subframe, + FLAC__BitWriter *frame +) +{ + switch(subframe->type) { + case FLAC__SUBFRAME_TYPE_CONSTANT: + if(!FLAC__subframe_add_constant(&(subframe->data.constant), subframe_bps, subframe->wasted_bits, frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return false; + } + break; + case FLAC__SUBFRAME_TYPE_FIXED: + if(!FLAC__subframe_add_fixed(&(subframe->data.fixed), blocksize - subframe->data.fixed.order, subframe_bps, subframe->wasted_bits, frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return false; + } + break; + case FLAC__SUBFRAME_TYPE_LPC: + if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return false; + } + break; + case FLAC__SUBFRAME_TYPE_VERBATIM: + if(!FLAC__subframe_add_verbatim(&(subframe->data.verbatim), blocksize, subframe_bps, subframe->wasted_bits, frame)) { + encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; + return false; + } + break; + default: + FLAC__ASSERT(0); + } + + return true; +} + +#define SPOTCHECK_ESTIMATE 0 +#if SPOTCHECK_ESTIMATE +static void spotcheck_subframe_estimate_( + FLAC__StreamEncoder *encoder, + unsigned blocksize, + unsigned subframe_bps, + const FLAC__Subframe *subframe, + unsigned estimate +) +{ + FLAC__bool ret; + FLAC__BitWriter *frame = FLAC__bitwriter_new(); + if(frame == 0) { + fprintf(stderr, "EST: can't allocate frame\n"); + return; + } + if(!FLAC__bitwriter_init(frame)) { + fprintf(stderr, "EST: can't init frame\n"); + return; + } + ret = add_subframe_(encoder, blocksize, subframe_bps, subframe, frame); + FLAC__ASSERT(ret); + { + const unsigned actual = FLAC__bitwriter_get_input_bits_unconsumed(frame); + if(estimate != actual) + fprintf(stderr, "EST: bad, frame#%u sub#%%d type=%8s est=%u, actual=%u, delta=%d\n", encoder->private_->current_frame_number, FLAC__SubframeTypeString[subframe->type], estimate, actual, (int)actual-(int)estimate); + } + FLAC__bitwriter_delete(frame); +} +#endif + +unsigned evaluate_constant_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal, + unsigned blocksize, + unsigned subframe_bps, + FLAC__Subframe *subframe +) +{ + unsigned estimate; + subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT; + subframe->data.constant.value = signal; + + estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + subframe_bps; + +#if SPOTCHECK_ESTIMATE + spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); +#else + (void)encoder, (void)blocksize; +#endif + + return estimate; +} + +unsigned evaluate_fixed_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal[], + FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned raw_bits_per_partition[], + unsigned blocksize, + unsigned subframe_bps, + unsigned order, + unsigned rice_parameter, + unsigned rice_parameter_limit, + unsigned min_partition_order, + unsigned max_partition_order, + FLAC__bool do_escape_coding, + unsigned rice_parameter_search_dist, + FLAC__Subframe *subframe, + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents +) +{ + unsigned i, residual_bits, estimate; + const unsigned residual_samples = blocksize - order; + + FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual); + + subframe->type = FLAC__SUBFRAME_TYPE_FIXED; + + subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; + subframe->data.fixed.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents; + subframe->data.fixed.residual = residual; + + residual_bits = + find_best_partition_order_( + encoder->private_, + residual, + abs_residual_partition_sums, + raw_bits_per_partition, + residual_samples, + order, + rice_parameter, + rice_parameter_limit, + min_partition_order, + max_partition_order, + subframe_bps, + do_escape_coding, + rice_parameter_search_dist, + &subframe->data.fixed.entropy_coding_method + ); + + subframe->data.fixed.order = order; + for(i = 0; i < order; i++) + subframe->data.fixed.warmup[i] = signal[i]; + + estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps) + residual_bits; + +#if SPOTCHECK_ESTIMATE + spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); +#endif + + return estimate; +} + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +unsigned evaluate_lpc_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal[], + FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned raw_bits_per_partition[], + const FLAC__real lp_coeff[], + unsigned blocksize, + unsigned subframe_bps, + unsigned order, + unsigned qlp_coeff_precision, + unsigned rice_parameter, + unsigned rice_parameter_limit, + unsigned min_partition_order, + unsigned max_partition_order, + FLAC__bool do_escape_coding, + unsigned rice_parameter_search_dist, + FLAC__Subframe *subframe, + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents +) +{ + FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /* WATCHOUT: the size is important; some x86 intrinsic routines need more than lpc order elements */ + unsigned i, residual_bits, estimate; + int quantization, ret; + const unsigned residual_samples = blocksize - order; + + /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */ + if(subframe_bps <= 17) { + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER); + qlp_coeff_precision = flac_min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order)); + } + + ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization); + if(ret != 0) + return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */ + + if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) + if(subframe_bps <= 16 && qlp_coeff_precision <= 16) + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual); + else + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual); + else + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual); + + subframe->type = FLAC__SUBFRAME_TYPE_LPC; + + subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; + subframe->data.lpc.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents; + subframe->data.lpc.residual = residual; + + residual_bits = + find_best_partition_order_( + encoder->private_, + residual, + abs_residual_partition_sums, + raw_bits_per_partition, + residual_samples, + order, + rice_parameter, + rice_parameter_limit, + min_partition_order, + max_partition_order, + subframe_bps, + do_escape_coding, + rice_parameter_search_dist, + &subframe->data.lpc.entropy_coding_method + ); + + subframe->data.lpc.order = order; + subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision; + subframe->data.lpc.quantization_level = quantization; + memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER); + for(i = 0; i < order; i++) + subframe->data.lpc.warmup[i] = signal[i]; + + estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits; + +#if SPOTCHECK_ESTIMATE + spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); +#endif + + return estimate; +} +#endif + +unsigned evaluate_verbatim_subframe_( + FLAC__StreamEncoder *encoder, + const FLAC__int32 signal[], + unsigned blocksize, + unsigned subframe_bps, + FLAC__Subframe *subframe +) +{ + unsigned estimate; + + subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM; + + subframe->data.verbatim.data = signal; + + estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps); + +#if SPOTCHECK_ESTIMATE + spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); +#else + (void)encoder; +#endif + + return estimate; +} + +unsigned find_best_partition_order_( + FLAC__StreamEncoderPrivate *private_, + const FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned raw_bits_per_partition[], + unsigned residual_samples, + unsigned predictor_order, + unsigned rice_parameter, + unsigned rice_parameter_limit, + unsigned min_partition_order, + unsigned max_partition_order, + unsigned bps, + FLAC__bool do_escape_coding, + unsigned rice_parameter_search_dist, + FLAC__EntropyCodingMethod *best_ecm +) +{ + unsigned residual_bits, best_residual_bits = 0; + unsigned best_parameters_index = 0; + unsigned best_partition_order = 0; + const unsigned blocksize = residual_samples + predictor_order; + + max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); + min_partition_order = flac_min(min_partition_order, max_partition_order); + + private_->local_precompute_partition_info_sums(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); + + if(do_escape_coding) + precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); + + { + int partition_order; + unsigned sum; + + for(partition_order = (int)max_partition_order, sum = 0; partition_order >= (int)min_partition_order; partition_order--) { + if(! + set_partitioned_rice_( +#ifdef EXACT_RICE_BITS_CALCULATION + residual, +#endif + abs_residual_partition_sums+sum, + raw_bits_per_partition+sum, + residual_samples, + predictor_order, + rice_parameter, + rice_parameter_limit, + rice_parameter_search_dist, + (unsigned)partition_order, + do_escape_coding, + &private_->partitioned_rice_contents_extra[!best_parameters_index], + &residual_bits + ) + ) + { + FLAC__ASSERT(best_residual_bits != 0); + break; + } + sum += 1u << partition_order; + if(best_residual_bits == 0 || residual_bits < best_residual_bits) { + best_residual_bits = residual_bits; + best_parameters_index = !best_parameters_index; + best_partition_order = partition_order; + } + } + } + + best_ecm->data.partitioned_rice.order = best_partition_order; + + { + /* + * We are allowed to de-const the pointer based on our special + * knowledge; it is const to the outside world. + */ + FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents; + unsigned partition; + + /* save best parameters and raw_bits */ + FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, flac_max(6u, best_partition_order)); + memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partition_order))); + if(do_escape_coding) + memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order))); + /* + * Now need to check if the type should be changed to + * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the + * size of the rice parameters. + */ + for(partition = 0; partition < (1u<<best_partition_order); partition++) { + if(prc->parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2; + break; + } + } + } + + return best_residual_bits; +} + +void precompute_partition_info_sums_( + const FLAC__int32 residual[], + FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, + unsigned predictor_order, + unsigned min_partition_order, + unsigned max_partition_order, + unsigned bps +) +{ + const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; + unsigned partitions = 1u << max_partition_order; + + FLAC__ASSERT(default_partition_samples > predictor_order); + + /* first do max_partition_order */ + { + const unsigned threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); + unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); + /* WATCHOUT: "bps + FLAC__MAX_EXTRA_RESIDUAL_BPS" is the maximum assumed size of the average residual magnitude */ + if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { + for(partition = residual_sample = 0; partition < partitions; partition++) { + FLAC__uint32 abs_residual_partition_sum = 0; + end += default_partition_samples; + for( ; residual_sample < end; residual_sample++) + abs_residual_partition_sum += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */ + abs_residual_partition_sums[partition] = abs_residual_partition_sum; + } + } + else { /* have to pessimistically use 64 bits for accumulator */ + for(partition = residual_sample = 0; partition < partitions; partition++) { + FLAC__uint64 abs_residual_partition_sum64 = 0; + end += default_partition_samples; + for( ; residual_sample < end; residual_sample++) + abs_residual_partition_sum64 += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */ + abs_residual_partition_sums[partition] = abs_residual_partition_sum64; + } + } + } + + /* now merge partitions for lower orders */ + { + unsigned from_partition = 0, to_partition = partitions; + int partition_order; + for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { + unsigned i; + partitions >>= 1; + for(i = 0; i < partitions; i++) { + abs_residual_partition_sums[to_partition++] = + abs_residual_partition_sums[from_partition ] + + abs_residual_partition_sums[from_partition+1]; + from_partition += 2; + } + } + } +} + +void precompute_partition_info_escapes_( + const FLAC__int32 residual[], + unsigned raw_bits_per_partition[], + unsigned residual_samples, + unsigned predictor_order, + unsigned min_partition_order, + unsigned max_partition_order +) +{ + int partition_order; + unsigned from_partition, to_partition = 0; + const unsigned blocksize = residual_samples + predictor_order; + + /* first do max_partition_order */ + for(partition_order = (int)max_partition_order; partition_order >= 0; partition_order--) { + FLAC__int32 r; + FLAC__uint32 rmax; + unsigned partition, partition_sample, partition_samples, residual_sample; + const unsigned partitions = 1u << partition_order; + const unsigned default_partition_samples = blocksize >> partition_order; + + FLAC__ASSERT(default_partition_samples > predictor_order); + + for(partition = residual_sample = 0; partition < partitions; partition++) { + partition_samples = default_partition_samples; + if(partition == 0) + partition_samples -= predictor_order; + rmax = 0; + for(partition_sample = 0; partition_sample < partition_samples; partition_sample++) { + r = residual[residual_sample++]; + /* OPT: maybe faster: rmax |= r ^ (r>>31) */ + if(r < 0) + rmax |= ~r; + else + rmax |= r; + } + /* now we know all residual values are in the range [-rmax-1,rmax] */ + raw_bits_per_partition[partition] = rmax? FLAC__bitmath_ilog2(rmax) + 2 : 1; + } + to_partition = partitions; + break; /*@@@ yuck, should remove the 'for' loop instead */ + } + + /* now merge partitions for lower orders */ + for(from_partition = 0, --partition_order; partition_order >= (int)min_partition_order; partition_order--) { + unsigned m; + unsigned i; + const unsigned partitions = 1u << partition_order; + for(i = 0; i < partitions; i++) { + m = raw_bits_per_partition[from_partition]; + from_partition++; + raw_bits_per_partition[to_partition] = flac_max(m, raw_bits_per_partition[from_partition]); + from_partition++; + to_partition++; + } + } +} + +#ifdef EXACT_RICE_BITS_CALCULATION +static inline unsigned count_rice_bits_in_partition_( + const unsigned rice_parameter, + const unsigned partition_samples, + const FLAC__int32 *residual +) +{ + unsigned i, partition_bits = + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ + (1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */ + ; + for(i = 0; i < partition_samples; i++) + partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter ); + return partition_bits; +} +#else +static inline unsigned count_rice_bits_in_partition_( + const unsigned rice_parameter, + const unsigned partition_samples, + const FLAC__uint64 abs_residual_partition_sum +) +{ + return + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ + (1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */ + ( + rice_parameter? + (unsigned)(abs_residual_partition_sum >> (rice_parameter-1)) /* rice_parameter-1 because the real coder sign-folds instead of using a sign bit */ + : (unsigned)(abs_residual_partition_sum << 1) /* can't shift by negative number, so reverse */ + ) + - (partition_samples >> 1) + /* -(partition_samples>>1) to subtract out extra contributions to the abs_residual_partition_sum. + * The actual number of bits used is closer to the sum(for all i in the partition) of abs(residual[i])>>(rice_parameter-1) + * By using the abs_residual_partition sum, we also add in bits in the LSBs that would normally be shifted out. + * So the subtraction term tries to guess how many extra bits were contributed. + * If the LSBs are randomly distributed, this should average to 0.5 extra bits per sample. + */ + ; +} +#endif + +FLAC__bool set_partitioned_rice_( +#ifdef EXACT_RICE_BITS_CALCULATION + const FLAC__int32 residual[], +#endif + const FLAC__uint64 abs_residual_partition_sums[], + const unsigned raw_bits_per_partition[], + const unsigned residual_samples, + const unsigned predictor_order, + const unsigned suggested_rice_parameter, + const unsigned rice_parameter_limit, + const unsigned rice_parameter_search_dist, + const unsigned partition_order, + const FLAC__bool search_for_escapes, + FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, + unsigned *bits +) +{ + unsigned rice_parameter, partition_bits; + unsigned best_partition_bits, best_rice_parameter = 0; + unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; + unsigned *parameters, *raw_bits; +#ifdef ENABLE_RICE_PARAMETER_SEARCH + unsigned min_rice_parameter, max_rice_parameter; +#else + (void)rice_parameter_search_dist; +#endif + + FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); + FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); + + FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order)); + parameters = partitioned_rice_contents->parameters; + raw_bits = partitioned_rice_contents->raw_bits; + + if(partition_order == 0) { + best_partition_bits = (unsigned)(-1); +#ifdef ENABLE_RICE_PARAMETER_SEARCH + if(rice_parameter_search_dist) { + if(suggested_rice_parameter < rice_parameter_search_dist) + min_rice_parameter = 0; + else + min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; + max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist; + if(max_rice_parameter >= rice_parameter_limit) { +#ifdef DEBUG_VERBOSE + fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1); +#endif + max_rice_parameter = rice_parameter_limit - 1; + } + } + else + min_rice_parameter = max_rice_parameter = suggested_rice_parameter; + + for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { +#else + rice_parameter = suggested_rice_parameter; +#endif +#ifdef EXACT_RICE_BITS_CALCULATION + partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, residual); +#else + partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, abs_residual_partition_sums[0]); +#endif + if(partition_bits < best_partition_bits) { + best_rice_parameter = rice_parameter; + best_partition_bits = partition_bits; + } +#ifdef ENABLE_RICE_PARAMETER_SEARCH + } +#endif + if(search_for_escapes) { + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; + if(partition_bits <= best_partition_bits) { + raw_bits[0] = raw_bits_per_partition[0]; + best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ + best_partition_bits = partition_bits; + } + else + raw_bits[0] = 0; + } + parameters[0] = best_rice_parameter; + bits_ += best_partition_bits; + } + else { + unsigned partition, residual_sample; + unsigned partition_samples; + FLAC__uint64 mean, k; + const unsigned partitions = 1u << partition_order; + for(partition = residual_sample = 0; partition < partitions; partition++) { + partition_samples = (residual_samples+predictor_order) >> partition_order; + if(partition == 0) { + if(partition_samples <= predictor_order) + return false; + else + partition_samples -= predictor_order; + } + mean = abs_residual_partition_sums[partition]; + /* we are basically calculating the size in bits of the + * average residual magnitude in the partition: + * rice_parameter = floor(log2(mean/partition_samples)) + * 'mean' is not a good name for the variable, it is + * actually the sum of magnitudes of all residual values + * in the partition, so the actual mean is + * mean/partition_samples + */ +#if 0 /* old simple code */ + for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) + ; +#else +#if defined FLAC__CPU_X86_64 /* and other 64-bit arch, too */ + if(mean <= 0x80000000/512) { /* 512: more or less optimal for both 16- and 24-bit input */ +#else + if(mean <= 0x80000000/8) { /* 32-bit arch: use 32-bit math if possible */ +#endif + FLAC__uint32 k2, mean2 = (FLAC__uint32) mean; + rice_parameter = 0; k2 = partition_samples; + while(k2*8 < mean2) { /* requires: mean <= (2^31)/8 */ + rice_parameter += 4; k2 <<= 4; /* tuned for 16-bit input */ + } + while(k2 < mean2) { /* requires: mean <= 2^31 */ + rice_parameter++; k2 <<= 1; + } + } + else { + rice_parameter = 0; k = partition_samples; + if(mean <= FLAC__U64L(0x8000000000000000)/128) /* usually mean is _much_ smaller than this value */ + while(k*128 < mean) { /* requires: mean <= (2^63)/128 */ + rice_parameter += 8; k <<= 8; /* tuned for 24-bit input */ + } + while(k < mean) { /* requires: mean <= 2^63 */ + rice_parameter++; k <<= 1; + } + } +#endif + if(rice_parameter >= rice_parameter_limit) { +#ifdef DEBUG_VERBOSE + fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); +#endif + rice_parameter = rice_parameter_limit - 1; + } + + best_partition_bits = (unsigned)(-1); +#ifdef ENABLE_RICE_PARAMETER_SEARCH + if(rice_parameter_search_dist) { + if(rice_parameter < rice_parameter_search_dist) + min_rice_parameter = 0; + else + min_rice_parameter = rice_parameter - rice_parameter_search_dist; + max_rice_parameter = rice_parameter + rice_parameter_search_dist; + if(max_rice_parameter >= rice_parameter_limit) { +#ifdef DEBUG_VERBOSE + fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1); +#endif + max_rice_parameter = rice_parameter_limit - 1; + } + } + else + min_rice_parameter = max_rice_parameter = rice_parameter; + + for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { +#endif +#ifdef EXACT_RICE_BITS_CALCULATION + partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample); +#else + partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]); +#endif + if(partition_bits < best_partition_bits) { + best_rice_parameter = rice_parameter; + best_partition_bits = partition_bits; + } +#ifdef ENABLE_RICE_PARAMETER_SEARCH + } +#endif + if(search_for_escapes) { + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; + if(partition_bits <= best_partition_bits) { + raw_bits[partition] = raw_bits_per_partition[partition]; + best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ + best_partition_bits = partition_bits; + } + else + raw_bits[partition] = 0; + } + parameters[partition] = best_rice_parameter; + bits_ += best_partition_bits; + residual_sample += partition_samples; + } + } + + *bits = bits_; + return true; +} + +unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples) +{ + unsigned i, shift; + FLAC__int32 x = 0; + + for(i = 0; i < samples && !(x&1); i++) + x |= signal[i]; + + if(x == 0) { + shift = 0; + } + else { + for(shift = 0; !(x&1); shift++) + x >>= 1; + } + + if(shift > 0) { + for(i = 0; i < samples; i++) + signal[i] >>= shift; + } + + return shift; +} + +void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], unsigned input_offset, unsigned channels, unsigned wide_samples) +{ + unsigned channel; + + for(channel = 0; channel < channels; channel++) + memcpy(&fifo->data[channel][fifo->tail], &input[channel][input_offset], sizeof(FLAC__int32) * wide_samples); + + fifo->tail += wide_samples; + + FLAC__ASSERT(fifo->tail <= fifo->size); +} + +void append_to_verify_fifo_interleaved_(verify_input_fifo *fifo, const FLAC__int32 input[], unsigned input_offset, unsigned channels, unsigned wide_samples) +{ + unsigned channel; + unsigned sample, wide_sample; + unsigned tail = fifo->tail; + + sample = input_offset * channels; + for(wide_sample = 0; wide_sample < wide_samples; wide_sample++) { + for(channel = 0; channel < channels; channel++) + fifo->data[channel][tail] = input[sample++]; + tail++; + } + fifo->tail = tail; + + FLAC__ASSERT(fifo->tail <= fifo->size); +} + +FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) +{ + FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data; + const size_t encoded_bytes = encoder->private_->verify.output.bytes; + (void)decoder; + + if(encoder->private_->verify.needs_magic_hack) { + FLAC__ASSERT(*bytes >= FLAC__STREAM_SYNC_LENGTH); + *bytes = FLAC__STREAM_SYNC_LENGTH; + memcpy(buffer, FLAC__STREAM_SYNC_STRING, *bytes); + encoder->private_->verify.needs_magic_hack = false; + } + else { + if(encoded_bytes == 0) { + /* + * If we get here, a FIFO underflow has occurred, + * which means there is a bug somewhere. + */ + FLAC__ASSERT(0); + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + } + else if(encoded_bytes < *bytes) + *bytes = encoded_bytes; + memcpy(buffer, encoder->private_->verify.output.data, *bytes); + encoder->private_->verify.output.data += *bytes; + encoder->private_->verify.output.bytes -= *bytes; + } + + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; +} + +FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) +{ + FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder *)client_data; + unsigned channel; + const unsigned channels = frame->header.channels; + const unsigned blocksize = frame->header.blocksize; + const unsigned bytes_per_block = sizeof(FLAC__int32) * blocksize; + + (void)decoder; + + for(channel = 0; channel < channels; channel++) { + if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) { + unsigned i, sample = 0; + FLAC__int32 expect = 0, got = 0; + + for(i = 0; i < blocksize; i++) { + if(buffer[channel][i] != encoder->private_->verify.input_fifo.data[channel][i]) { + sample = i; + expect = (FLAC__int32)encoder->private_->verify.input_fifo.data[channel][i]; + got = (FLAC__int32)buffer[channel][i]; + break; + } + } + FLAC__ASSERT(i < blocksize); + FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + encoder->private_->verify.error_stats.absolute_sample = frame->header.number.sample_number + sample; + encoder->private_->verify.error_stats.frame_number = (unsigned)(frame->header.number.sample_number / blocksize); + encoder->private_->verify.error_stats.channel = channel; + encoder->private_->verify.error_stats.sample = sample; + encoder->private_->verify.error_stats.expected = expect; + encoder->private_->verify.error_stats.got = got; + encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA; + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + } + /* dequeue the frame from the fifo */ + encoder->private_->verify.input_fifo.tail -= blocksize; + FLAC__ASSERT(encoder->private_->verify.input_fifo.tail <= OVERREAD_); + for(channel = 0; channel < channels; channel++) + memmove(&encoder->private_->verify.input_fifo.data[channel][0], &encoder->private_->verify.input_fifo.data[channel][blocksize], encoder->private_->verify.input_fifo.tail * sizeof(encoder->private_->verify.input_fifo.data[0][0])); + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; +} + +void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + (void)decoder, (void)metadata, (void)client_data; +} + +void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data; + (void)decoder, (void)status; + encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; +} + +FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) +{ + (void)client_data; + + *bytes = fread(buffer, 1, *bytes, encoder->private_->file); + if (*bytes == 0) { + if (feof(encoder->private_->file)) + return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM; + else if (ferror(encoder->private_->file)) + return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + } + return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; +} + +FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) +{ + (void)client_data; + + if(fseeko(encoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) + return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; + else + return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; +} + +FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) +{ + FLAC__off_t offset; + + (void)client_data; + + offset = ftello(encoder->private_->file); + + if(offset < 0) { + return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR; + } + else { + *absolute_byte_offset = (FLAC__uint64)offset; + return FLAC__STREAM_ENCODER_TELL_STATUS_OK; + } +} + +#ifdef FLAC__VALGRIND_TESTING +static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t ret = fwrite(ptr, size, nmemb, stream); + if(!ferror(stream)) + fflush(stream); + return ret; +} +#else +#define local__fwrite fwrite +#endif + +FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data) +{ + (void)client_data, (void)current_frame; + + if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, encoder->private_->file) == bytes) { + FLAC__bool call_it = 0 != encoder->private_->progress_callback && ( +#if FLAC__HAS_OGG + /* We would like to be able to use 'samples > 0' in the + * clause here but currently because of the nature of our + * Ogg writing implementation, 'samples' is always 0 (see + * ogg_encoder_aspect.c). The downside is extra progress + * callbacks. + */ + encoder->private_->is_ogg? true : +#endif + samples > 0 + ); + if(call_it) { + /* NOTE: We have to add +bytes, +samples, and +1 to the stats + * because at this point in the callback chain, the stats + * have not been updated. Only after we return and control + * gets back to write_frame_() are the stats updated + */ + encoder->private_->progress_callback(encoder, encoder->private_->bytes_written+bytes, encoder->private_->samples_written+samples, encoder->private_->frames_written+(samples?1:0), encoder->private_->total_frames_estimate, encoder->private_->client_data); + } + return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; + } + else + return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; +} + +/* + * This will forcibly set stdout to binary mode (for OSes that require it) + */ +FILE *get_binary_stdout_(void) +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdout), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdout), _O_BINARY); +#elif defined __EMX__ + setmode(fileno(stdout), O_BINARY); +#endif + + return stdout; +} diff --git a/deps/flac-1.3.2/src/libFLAC/stream_encoder_framing.c b/deps/flac-1.3.2/src/libFLAC/stream_encoder_framing.c new file mode 100644 index 0000000..0929cd7 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/stream_encoder_framing.c @@ -0,0 +1,554 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <string.h> /* for strlen() */ +#include "private/stream_encoder_framing.h" +#include "private/crc.h" +#include "FLAC/assert.h" +#include "share/compat.h" + +static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method); +static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended); + +FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw) +{ + unsigned i, j; + const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING); + + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN)) + return false; + + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN)) + return false; + + /* + * First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string + */ + i = metadata->length; + if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry); + i -= metadata->data.vorbis_comment.vendor_string.length; + i += vendor_string_length; + } + FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); + /* double protection */ + if(i >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, i, FLAC__STREAM_METADATA_LENGTH_LEN)) + return false; + + switch(metadata->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + FLAC__ASSERT(metadata->data.stream_info.min_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)) + return false; + FLAC__ASSERT(metadata->data.stream_info.max_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) + return false; + FLAC__ASSERT(metadata->data.stream_info.min_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_framesize, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) + return false; + FLAC__ASSERT(metadata->data.stream_info.max_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_framesize, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) + return false; + FLAC__ASSERT(FLAC__format_sample_rate_is_valid(metadata->data.stream_info.sample_rate)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.sample_rate, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) + return false; + FLAC__ASSERT(metadata->data.stream_info.channels > 0); + FLAC__ASSERT(metadata->data.stream_info.channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.channels-1, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) + return false; + FLAC__ASSERT(metadata->data.stream_info.bits_per_sample > 0); + FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) + return false; + FLAC__ASSERT(metadata->data.stream_info.total_samples < (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)); + if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16)) + return false; + break; + case FLAC__METADATA_TYPE_PADDING: + if(!FLAC__bitwriter_write_zeroes(bw, metadata->length * 8)) + return false; + break; + case FLAC__METADATA_TYPE_APPLICATION: + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.data, metadata->length - (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))) + return false; + break; + case FLAC__METADATA_TYPE_SEEKTABLE: + for(i = 0; i < metadata->data.seek_table.num_points; i++) { + if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) + return false; + } + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length)) + return false; + if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.num_comments)) + return false; + for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { + if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.comments[i].length)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length)) + return false; + } + break; + case FLAC__METADATA_TYPE_CUESHEET: + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); + if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.cue_sheet.media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8)) + return false; + if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.cue_sheet.lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.is_cd? 1 : 0, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) + return false; + if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.num_tracks, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) + return false; + for(i = 0; i < metadata->data.cue_sheet.num_tracks; i++) { + const FLAC__StreamMetadata_CueSheet_Track *track = metadata->data.cue_sheet.tracks + i; + + if(!FLAC__bitwriter_write_raw_uint64(bw, track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, track->number, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) + return false; + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); + if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, track->type, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, track->pre_emphasis, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) + return false; + if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) + return false; + for(j = 0; j < track->num_indices; j++) { + const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + j; + + if(!FLAC__bitwriter_write_raw_uint64(bw, indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, indx->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) + return false; + if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) + return false; + } + } + break; + case FLAC__METADATA_TYPE_PICTURE: + { + size_t len; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.type, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) + return false; + len = strlen(metadata->data.picture.mime_type); + if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.picture.mime_type, len)) + return false; + len = strlen((const char *)metadata->data.picture.description); + if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.description, len)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.data_length, FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.data, metadata->data.picture.data_length)) + return false; + } + break; + default: + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.unknown.data, metadata->length)) + return false; + break; + } + + FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); + return true; +} + +FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw) +{ + unsigned u, blocksize_hint, sample_rate_hint; + FLAC__byte crc; + + FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); + + if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN)) + return false; + + if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN)) + return false; + + if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) + return false; + + FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); + /* when this assertion holds true, any legal blocksize can be expressed in the frame header */ + FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u); + blocksize_hint = 0; + switch(header->blocksize) { + case 192: u = 1; break; + case 576: u = 2; break; + case 1152: u = 3; break; + case 2304: u = 4; break; + case 4608: u = 5; break; + case 256: u = 8; break; + case 512: u = 9; break; + case 1024: u = 10; break; + case 2048: u = 11; break; + case 4096: u = 12; break; + case 8192: u = 13; break; + case 16384: u = 14; break; + case 32768: u = 15; break; + default: + if(header->blocksize <= 0x100) + blocksize_hint = u = 6; + else + blocksize_hint = u = 7; + break; + } + if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) + return false; + + FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate)); + sample_rate_hint = 0; + switch(header->sample_rate) { + case 88200: u = 1; break; + case 176400: u = 2; break; + case 192000: u = 3; break; + case 8000: u = 4; break; + case 16000: u = 5; break; + case 22050: u = 6; break; + case 24000: u = 7; break; + case 32000: u = 8; break; + case 44100: u = 9; break; + case 48000: u = 10; break; + case 96000: u = 11; break; + default: + if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) + sample_rate_hint = u = 12; + else if(header->sample_rate % 10 == 0) + sample_rate_hint = u = 14; + else if(header->sample_rate <= 0xffff) + sample_rate_hint = u = 13; + else + u = 0; + break; + } + if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN)) + return false; + + FLAC__ASSERT(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS); + switch(header->channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + u = header->channels - 1; + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + FLAC__ASSERT(header->channels == 2); + u = 8; + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + FLAC__ASSERT(header->channels == 2); + u = 9; + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + FLAC__ASSERT(header->channels == 2); + u = 10; + break; + default: + FLAC__ASSERT(0); + } + if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN)) + return false; + + FLAC__ASSERT(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); + switch(header->bits_per_sample) { + case 8 : u = 1; break; + case 12: u = 2; break; + case 16: u = 4; break; + case 20: u = 5; break; + case 24: u = 6; break; + default: u = 0; break; + } + if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN)) + return false; + + if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN)) + return false; + + if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { + if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) + return false; + } + else { + if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number)) + return false; + } + + if(blocksize_hint) + if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16)) + return false; + + switch(sample_rate_hint) { + case 12: + if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 1000, 8)) + return false; + break; + case 13: + if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate, 16)) + return false; + break; + case 14: + if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 10, 16)) + return false; + break; + } + + /* write the CRC */ + if(!FLAC__bitwriter_get_write_crc8(bw, &crc)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, crc, FLAC__FRAME_HEADER_CRC_LEN)) + return false; + + return true; +} + +FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) +{ + FLAC__bool ok; + + ok = + FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) && + (wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) && + FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps) + ; + + return ok; +} + +FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) +{ + unsigned i; + + if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) + return false; + if(wasted_bits) + if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) + return false; + + for(i = 0; i < subframe->order; i++) + if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) + return false; + + if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) + return false; + switch(subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!add_residual_partitioned_rice_( + bw, + subframe->residual, + residual_samples, + subframe->order, + subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, + subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, + subframe->entropy_coding_method.data.partitioned_rice.order, + /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 + )) + return false; + break; + default: + FLAC__ASSERT(0); + } + + return true; +} + +FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) +{ + unsigned i; + + if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) + return false; + if(wasted_bits) + if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) + return false; + + for(i = 0; i < subframe->order; i++) + if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) + return false; + + if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) + return false; + if(!FLAC__bitwriter_write_raw_int32(bw, subframe->quantization_level, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) + return false; + for(i = 0; i < subframe->order; i++) + if(!FLAC__bitwriter_write_raw_int32(bw, subframe->qlp_coeff[i], subframe->qlp_coeff_precision)) + return false; + + if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) + return false; + switch(subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!add_residual_partitioned_rice_( + bw, + subframe->residual, + residual_samples, + subframe->order, + subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, + subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, + subframe->entropy_coding_method.data.partitioned_rice.order, + /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 + )) + return false; + break; + default: + FLAC__ASSERT(0); + } + + return true; +} + +FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) +{ + unsigned i; + const FLAC__int32 *signal = subframe->data; + + if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) + return false; + if(wasted_bits) + if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) + return false; + + for(i = 0; i < samples; i++) + if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps)) + return false; + + return true; +} + +FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method) +{ + if(!FLAC__bitwriter_write_raw_uint32(bw, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) + return false; + switch(method->type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) + return false; + break; + default: + FLAC__ASSERT(0); + } + return true; +} + +FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended) +{ + const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; + const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + + if(partition_order == 0) { + unsigned i; + + if(raw_bits[0] == 0) { + if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen)) + return false; + if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0])) + return false; + } + else { + FLAC__ASSERT(rice_parameters[0] == 0); + if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) + return false; + for(i = 0; i < residual_samples; i++) { + if(!FLAC__bitwriter_write_raw_int32(bw, residual[i], raw_bits[0])) + return false; + } + } + return true; + } + else { + unsigned i, j, k = 0, k_last = 0; + unsigned partition_samples; + const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order; + for(i = 0; i < (1u<<partition_order); i++) { + partition_samples = default_partition_samples; + if(i == 0) + partition_samples -= predictor_order; + k += partition_samples; + if(raw_bits[i] == 0) { + if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], plen)) + return false; + if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i])) + return false; + } + else { + if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) + return false; + if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) + return false; + for(j = k_last; j < k; j++) { + if(!FLAC__bitwriter_write_raw_int32(bw, residual[j], raw_bits[i])) + return false; + } + } + k_last = k; + } + return true; + } +} diff --git a/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_avx2.c b/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_avx2.c new file mode 100644 index 0000000..a94a02b --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_avx2.c @@ -0,0 +1,146 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/stream_encoder.h" +#include "private/bitmath.h" +#ifdef FLAC__AVX2_SUPPORTED + +#include <stdlib.h> /* for abs() */ +#include <immintrin.h> /* AVX2 */ +#include "FLAC/assert.h" + +FLAC__SSE_TARGET("avx2") +void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps) +{ + const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; + unsigned partitions = 1u << max_partition_order; + + FLAC__ASSERT(default_partition_samples > predictor_order); + + /* first do max_partition_order */ + { + const unsigned threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); + unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); + + if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { + for(partition = residual_sample = 0; partition < partitions; partition++) { + __m256i sum256 = _mm256_setzero_si256(); + __m128i sum128; + end += default_partition_samples; + + for( ; (int)residual_sample < (int)end-7; residual_sample+=8) { + __m256i res256 = _mm256_abs_epi32(_mm256_loadu_si256((const __m256i*)(residual+residual_sample))); + sum256 = _mm256_add_epi32(sum256, res256); + } + + sum128 = _mm_add_epi32(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256)); + + for( ; (int)residual_sample < (int)end-3; residual_sample+=4) { + __m128i res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); + sum128 = _mm_add_epi32(sum128, res128); + } + + for( ; residual_sample < end; residual_sample++) { + __m128i res128 = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + sum128 = _mm_add_epi32(sum128, res128); + } + + sum128 = _mm_hadd_epi32(sum128, sum128); + sum128 = _mm_hadd_epi32(sum128, sum128); + abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(sum128); +/* workaround for a bug in MSVC2015U2 - see https://connect.microsoft.com/VisualStudio/feedback/details/2659191/incorrect-code-generation-for-x86-64 */ +#if (defined _MSC_VER) && (_MSC_FULL_VER == 190023918) && (defined FLAC__CPU_X86_64) + abs_residual_partition_sums[partition] &= 0xFFFFFFFF; /**/ +#endif + } + } + else { /* have to pessimistically use 64 bits for accumulator */ + for(partition = residual_sample = 0; partition < partitions; partition++) { + __m256i sum256 = _mm256_setzero_si256(); + __m128i sum128; + end += default_partition_samples; + + for( ; (int)residual_sample < (int)end-3; residual_sample+=4) { + __m128i res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); + __m256i res256 = _mm256_cvtepu32_epi64(res128); + sum256 = _mm256_add_epi64(sum256, res256); + } + + sum128 = _mm_add_epi64(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256)); + + for( ; (int)residual_sample < (int)end-1; residual_sample+=2) { + __m128i res128 = _mm_abs_epi32(_mm_loadl_epi64((const __m128i*)(residual+residual_sample))); + res128 = _mm_cvtepu32_epi64(res128); + sum128 = _mm_add_epi64(sum128, res128); + } + + for( ; residual_sample < end; residual_sample++) { + __m128i res128 = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + sum128 = _mm_add_epi64(sum128, res128); + } + + sum128 = _mm_add_epi64(sum128, _mm_srli_si128(sum128, 8)); + _mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), sum128); + } + } + } + + /* now merge partitions for lower orders */ + { + unsigned from_partition = 0, to_partition = partitions; + int partition_order; + for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { + unsigned i; + partitions >>= 1; + for(i = 0; i < partitions; i++) { + abs_residual_partition_sums[to_partition++] = + abs_residual_partition_sums[from_partition ] + + abs_residual_partition_sums[from_partition+1]; + from_partition += 2; + } + } + } + _mm256_zeroupper(); +} + +#endif /* FLAC__AVX2_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ diff --git a/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_sse2.c b/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_sse2.c new file mode 100644 index 0000000..0f1d7aa --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_sse2.c @@ -0,0 +1,159 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/stream_encoder.h" +#include "private/bitmath.h" +#ifdef FLAC__SSE2_SUPPORTED + +#include <stdlib.h> /* for abs() */ +#include <emmintrin.h> /* SSE2 */ +#include "FLAC/assert.h" +#include "share/compat.h" + +FLAC__SSE_TARGET("sse2") +static inline __m128i local_abs_epi32(__m128i val) +{ + __m128i mask = _mm_srai_epi32(val, 31); + val = _mm_xor_si128(val, mask); + val = _mm_sub_epi32(val, mask); + return val; +} + + +FLAC__SSE_TARGET("sse2") +void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps) +{ + const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; + unsigned partitions = 1u << max_partition_order; + + FLAC__ASSERT(default_partition_samples > predictor_order); + + /* first do max_partition_order */ + { + const unsigned threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); + unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); + + if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { + for(partition = residual_sample = 0; partition < partitions; partition++) { + __m128i mm_sum = _mm_setzero_si128(); + unsigned e1, e3; + end += default_partition_samples; + + e1 = (residual_sample + 3) & ~3; e3 = end & ~3; + if(e1 > end) + e1 = end; /* try flac -l 1 -b 16 and you'll be here */ + + /* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */ + for( ; residual_sample < e1; residual_sample++) { + __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + mm_sum = _mm_add_epi32(mm_sum, mm_res); + } + + for( ; residual_sample < e3; residual_sample+=4) { + __m128i mm_res = local_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); + mm_sum = _mm_add_epi32(mm_sum, mm_res); + } + + for( ; residual_sample < end; residual_sample++) { + __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + mm_sum = _mm_add_epi32(mm_sum, mm_res); + } + + mm_sum = _mm_add_epi32(mm_sum, _mm_srli_si128(mm_sum, 8)); + mm_sum = _mm_add_epi32(mm_sum, _mm_srli_si128(mm_sum, 4)); + abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum); +/* workaround for a bug in MSVC2015U2 - see https://connect.microsoft.com/VisualStudio/feedback/details/2659191/incorrect-code-generation-for-x86-64 */ +#if (defined _MSC_VER) && (_MSC_FULL_VER == 190023918) && (defined FLAC__CPU_X86_64) + abs_residual_partition_sums[partition] &= 0xFFFFFFFF; +#endif + } + } + else { /* have to pessimistically use 64 bits for accumulator */ + for(partition = residual_sample = 0; partition < partitions; partition++) { + __m128i mm_sum = _mm_setzero_si128(); + unsigned e1, e3; + end += default_partition_samples; + + e1 = (residual_sample + 1) & ~1; e3 = end & ~1; + FLAC__ASSERT(e1 <= end); + + for( ; residual_sample < e1; residual_sample++) { + __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); /* 0 0 0 |r0| == 00 |r0_64| */ + mm_sum = _mm_add_epi64(mm_sum, mm_res); + } + + for( ; residual_sample < e3; residual_sample+=2) { + __m128i mm_res = local_abs_epi32(_mm_loadl_epi64((const __m128i*)(residual+residual_sample))); /* 0 0 |r1| |r0| */ + mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */ + mm_sum = _mm_add_epi64(mm_sum, mm_res); + } + + for( ; residual_sample < end; residual_sample++) { + __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + mm_sum = _mm_add_epi64(mm_sum, mm_res); + } + + mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8)); + _mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum); + } + } + } + + /* now merge partitions for lower orders */ + { + unsigned from_partition = 0, to_partition = partitions; + int partition_order; + for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { + unsigned i; + partitions >>= 1; + for(i = 0; i < partitions; i++) { + abs_residual_partition_sums[to_partition++] = + abs_residual_partition_sums[from_partition ] + + abs_residual_partition_sums[from_partition+1]; + from_partition += 2; + } + } + } +} + +#endif /* FLAC__SSE2_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ diff --git a/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_ssse3.c b/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_ssse3.c new file mode 100644 index 0000000..21a08fc --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/stream_encoder_intrin_ssse3.c @@ -0,0 +1,148 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "private/cpu.h" + +#ifndef FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +#include "private/stream_encoder.h" +#include "private/bitmath.h" +#ifdef FLAC__SSSE3_SUPPORTED + +#include <stdlib.h> /* for abs() */ +#include <tmmintrin.h> /* SSSE3 */ +#include "FLAC/assert.h" + +FLAC__SSE_TARGET("ssse3") +void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], + unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps) +{ + const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; + unsigned partitions = 1u << max_partition_order; + + FLAC__ASSERT(default_partition_samples > predictor_order); + + /* first do max_partition_order */ + { + const unsigned threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); + unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); + + if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { + for(partition = residual_sample = 0; partition < partitions; partition++) { + __m128i mm_sum = _mm_setzero_si128(); + unsigned e1, e3; + end += default_partition_samples; + + e1 = (residual_sample + 3) & ~3; e3 = end & ~3; + if(e1 > end) + e1 = end; /* try flac -l 1 -b 16 and you'll be here */ + + /* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */ + for( ; residual_sample < e1; residual_sample++) { + __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + mm_sum = _mm_add_epi32(mm_sum, mm_res); + } + + for( ; residual_sample < e3; residual_sample+=4) { + __m128i mm_res = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); + mm_sum = _mm_add_epi32(mm_sum, mm_res); + } + + for( ; residual_sample < end; residual_sample++) { + __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + mm_sum = _mm_add_epi32(mm_sum, mm_res); + } + + mm_sum = _mm_hadd_epi32(mm_sum, mm_sum); + mm_sum = _mm_hadd_epi32(mm_sum, mm_sum); + abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum); +/* workaround for a bug in MSVC2015U2 - see https://connect.microsoft.com/VisualStudio/feedback/details/2659191/incorrect-code-generation-for-x86-64 */ +#if (defined _MSC_VER) && (_MSC_FULL_VER == 190023918) && (defined FLAC__CPU_X86_64) + abs_residual_partition_sums[partition] &= 0xFFFFFFFF; +#endif + } + } + else { /* have to pessimistically use 64 bits for accumulator */ + for(partition = residual_sample = 0; partition < partitions; partition++) { + __m128i mm_sum = _mm_setzero_si128(); + unsigned e1, e3; + end += default_partition_samples; + + e1 = (residual_sample + 1) & ~1; e3 = end & ~1; + FLAC__ASSERT(e1 <= end); + + for( ; residual_sample < e1; residual_sample++) { + __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); /* 0 0 0 |r0| == 00 |r0_64| */ + mm_sum = _mm_add_epi64(mm_sum, mm_res); + } + + for( ; residual_sample < e3; residual_sample+=2) { + __m128i mm_res = _mm_abs_epi32(_mm_loadl_epi64((const __m128i*)(residual+residual_sample))); /* 0 0 |r1| |r0| */ + mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */ + mm_sum = _mm_add_epi64(mm_sum, mm_res); + } + + for( ; residual_sample < end; residual_sample++) { + __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); + mm_sum = _mm_add_epi64(mm_sum, mm_res); + } + + mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8)); + _mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum); + } + } + } + + /* now merge partitions for lower orders */ + { + unsigned from_partition = 0, to_partition = partitions; + int partition_order; + for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { + unsigned i; + partitions >>= 1; + for(i = 0; i < partitions; i++) { + abs_residual_partition_sums[to_partition++] = + abs_residual_partition_sums[from_partition ] + + abs_residual_partition_sums[from_partition+1]; + from_partition += 2; + } + } + } +} + +#endif /* FLAC__SSSE3_SUPPORTED */ +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ +#endif /* FLAC__NO_ASM */ diff --git a/deps/flac-1.3.2/src/libFLAC/window.c b/deps/flac-1.3.2/src/libFLAC/window.c new file mode 100644 index 0000000..e977fd8 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/window.c @@ -0,0 +1,282 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2006-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <math.h> +#include "share/compat.h" +#include "FLAC/assert.h" +#include "FLAC/format.h" +#include "private/window.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY + + +void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + if (L & 1) { + for (n = 0; n <= N/2; n++) + window[n] = 2.0f * n / (float)N; + for (; n <= N; n++) + window[n] = 2.0f - 2.0f * n / (float)N; + } + else { + for (n = 0; n <= L/2-1; n++) + window[n] = 2.0f * n / (float)N; + for (; n <= N; n++) + window[n] = 2.0f - 2.0f * n / (float)N; + } +} + +void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N))); +} + +void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(0.42f - 0.5f * cos(2.0f * M_PI * n / N) + 0.08f * cos(4.0f * M_PI * n / N)); +} + +/* 4-term -92dB side-lobe */ +void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n <= N; n++) + window[n] = (FLAC__real)(0.35875f - 0.48829f * cos(2.0f * M_PI * n / N) + 0.14128f * cos(4.0f * M_PI * n / N) - 0.01168f * cos(6.0f * M_PI * n / N)); +} + +void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + const double N2 = (double)N / 2.; + FLAC__int32 n; + + for (n = 0; n <= N; n++) { + double k = ((double)n - N2) / N2; + k = 1.0f - k * k; + window[n] = (FLAC__real)(k * k); + } +} + +void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(1.0f - 1.93f * cos(2.0f * M_PI * n / N) + 1.29f * cos(4.0f * M_PI * n / N) - 0.388f * cos(6.0f * M_PI * n / N) + 0.0322f * cos(8.0f * M_PI * n / N)); +} + +void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev) +{ + const FLAC__int32 N = L - 1; + const double N2 = (double)N / 2.; + FLAC__int32 n; + + for (n = 0; n <= N; n++) { + const double k = ((double)n - N2) / (stddev * N2); + window[n] = (FLAC__real)exp(-0.5f * k * k); + } +} + +void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(0.54f - 0.46f * cos(2.0f * M_PI * n / N)); +} + +void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(2.0f * M_PI * n / N)); +} + +void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(0.402f - 0.498f * cos(2.0f * M_PI * n / N) + 0.098f * cos(4.0f * M_PI * n / N) - 0.001f * cos(6.0f * M_PI * n / N)); +} + +void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cos(2.0f*M_PI*n/N) + 0.1365995f*cos(4.0f*M_PI*n/N) - 0.0106411f*cos(6.0f*M_PI*n/N)); +} + +void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L) +{ + FLAC__int32 n; + + for (n = 0; n < L; n++) + window[n] = 1.0f; +} + +void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L) +{ + FLAC__int32 n; + + if (L & 1) { + for (n = 1; n <= (L+1)/2; n++) + window[n-1] = 2.0f * n / ((float)L + 1.0f); + for (; n <= L; n++) + window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); + } + else { + for (n = 1; n <= L/2; n++) + window[n-1] = 2.0f * n / ((float)L + 1.0f); + for (; n <= L; n++) + window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); + } +} + +void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p) +{ + if (p <= 0.0) + FLAC__window_rectangle(window, L); + else if (p >= 1.0) + FLAC__window_hann(window, L); + else { + const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1; + FLAC__int32 n; + /* start with rectangle... */ + FLAC__window_rectangle(window, L); + /* ...replace ends with hann */ + if (Np > 0) { + for (n = 0; n <= Np; n++) { + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * n / Np)); + window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * (n+Np) / Np)); + } + } + } +} + +void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) +{ + const FLAC__int32 start_n = (FLAC__int32)(start * L); + const FLAC__int32 end_n = (FLAC__int32)(end * L); + const FLAC__int32 N = end_n - start_n; + FLAC__int32 Np, n, i; + + if (p <= 0.0f) + FLAC__window_partial_tukey(window, L, 0.05f, start, end); + else if (p >= 1.0f) + FLAC__window_partial_tukey(window, L, 0.95f, start, end); + else { + + Np = (FLAC__int32)(p / 2.0f * N); + + for (n = 0; n < start_n && n < L; n++) + window[n] = 0.0f; + for (i = 1; n < (start_n+Np) && n < L; n++, i++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np)); + for (; n < (end_n-Np) && n < L; n++) + window[n] = 1.0f; + for (i = Np; n < end_n && n < L; n++, i--) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np)); + for (; n < L; n++) + window[n] = 0.0f; + } +} + +void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) +{ + const FLAC__int32 start_n = (FLAC__int32)(start * L); + const FLAC__int32 end_n = (FLAC__int32)(end * L); + FLAC__int32 Ns, Ne, n, i; + + if (p <= 0.0f) + FLAC__window_punchout_tukey(window, L, 0.05f, start, end); + else if (p >= 1.0f) + FLAC__window_punchout_tukey(window, L, 0.95f, start, end); + else { + + Ns = (FLAC__int32)(p / 2.0f * start_n); + Ne = (FLAC__int32)(p / 2.0f * (L - end_n)); + + for (n = 0, i = 1; n < Ns && n < L; n++, i++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns)); + for (; n < start_n-Ns && n < L; n++) + window[n] = 1.0f; + for (i = Ns; n < start_n && n < L; n++, i--) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns)); + for (; n < end_n && n < L; n++) + window[n] = 0.0f; + for (i = 1; n < end_n+Ne && n < L; n++, i++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne)); + for (; n < L - (Ne) && n < L; n++) + window[n] = 1.0f; + for (i = Ne; n < L; n++, i--) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne)); + } +} + +void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) +{ + const FLAC__int32 N = L - 1; + const double N2 = (double)N / 2.; + FLAC__int32 n; + + for (n = 0; n <= N; n++) { + const double k = ((double)n - N2) / N2; + window[n] = (FLAC__real)(1.0f - k * k); + } +} + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/deps/flac-1.3.2/src/libFLAC/windows_unicode_filenames.c b/deps/flac-1.3.2/src/libFLAC/windows_unicode_filenames.c new file mode 100644 index 0000000..2e9a136 --- /dev/null +++ b/deps/flac-1.3.2/src/libFLAC/windows_unicode_filenames.c @@ -0,0 +1,214 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <io.h> +#include "share/windows_unicode_filenames.h" + +/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */ +static wchar_t *wchar_from_utf8(const char *str) +{ + wchar_t *widestr; + int len; + + if (!str) + return NULL; + if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0) + return NULL; + if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL) + return NULL; + if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) { + free(widestr); + widestr = NULL; + } + + return widestr; +} + + +static FLAC__bool utf8_filenames = false; + + +void flac_internal_set_utf8_filenames(FLAC__bool flag) +{ + utf8_filenames = flag ? true : false; +} + +FLAC__bool flac_internal_get_utf8_filenames(void) +{ + return utf8_filenames; +} + +/* file functions */ + +FILE* flac_internal_fopen_utf8(const char *filename, const char *mode) +{ + if (!utf8_filenames) { + return fopen(filename, mode); + } else { + wchar_t *wname = NULL; + wchar_t *wmode = NULL; + FILE *f = NULL; + + do { + if (!(wname = wchar_from_utf8(filename))) break; + if (!(wmode = wchar_from_utf8(mode))) break; + f = _wfopen(wname, wmode); + } while(0); + + free(wname); + free(wmode); + + return f; + } +} + +int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer) +{ + if (!utf8_filenames) { + return _stat64(path, buffer); + } else { + wchar_t *wpath; + int ret; + + if (!(wpath = wchar_from_utf8(path))) return -1; + ret = _wstat64(wpath, buffer); + free(wpath); + + return ret; + } +} + +int flac_internal_chmod_utf8(const char *filename, int pmode) +{ + if (!utf8_filenames) { + return _chmod(filename, pmode); + } else { + wchar_t *wname; + int ret; + + if (!(wname = wchar_from_utf8(filename))) return -1; + ret = _wchmod(wname, pmode); + free(wname); + + return ret; + } +} + +int flac_internal_utime_utf8(const char *filename, struct utimbuf *times) +{ + if (!utf8_filenames) { + return utime(filename, times); + } else { + wchar_t *wname; + struct __utimbuf64 ut; + int ret; + + if (!(wname = wchar_from_utf8(filename))) return -1; + ut.actime = times->actime; + ut.modtime = times->modtime; + ret = _wutime64(wname, &ut); + free(wname); + + return ret; + } +} + +int flac_internal_unlink_utf8(const char *filename) +{ + if (!utf8_filenames) { + return _unlink(filename); + } else { + wchar_t *wname; + int ret; + + if (!(wname = wchar_from_utf8(filename))) return -1; + ret = _wunlink(wname); + free(wname); + + return ret; + } +} + +int flac_internal_rename_utf8(const char *oldname, const char *newname) +{ + if (!utf8_filenames) { + return rename(oldname, newname); + } else { + wchar_t *wold = NULL; + wchar_t *wnew = NULL; + int ret = -1; + + do { + if (!(wold = wchar_from_utf8(oldname))) break; + if (!(wnew = wchar_from_utf8(newname))) break; + ret = _wrename(wold, wnew); + } while(0); + + free(wold); + free(wnew); + + return ret; + } +} + +HANDLE WINAPI flac_internal_CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) +{ +#if _MSC_VER > 1900 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + wchar_t *wname; + HANDLE handle = INVALID_HANDLE_VALUE; + + if ((wname = wchar_from_utf8(lpFileName)) != NULL) { + + handle = CreateFile2(wname, dwDesiredAccess, dwShareMode, CREATE_ALWAYS, NULL); + free(wname); + } + + return handle; +#else + if (!utf8_filenames) { + return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + } else { + wchar_t *wname; + HANDLE handle = INVALID_HANDLE_VALUE; + + if ((wname = wchar_from_utf8(lpFileName)) != NULL) { + handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + free(wname); + } + + return handle; + } +#endif +} diff --git a/deps/flac-1.3.2/src/share/Makefile.am b/deps/flac-1.3.2/src/share/Makefile.am new file mode 100644 index 0000000..82d0fc9 --- /dev/null +++ b/deps/flac-1.3.2/src/share/Makefile.am @@ -0,0 +1,100 @@ +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2002-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under different licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. + +AUTOMAKE_OPTIONS = subdir-objects + +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include + +EXTRA_DIST = \ + Makefile.lite \ + README \ + getopt/Makefile.lite \ + getopt/getopt_static.vcproj \ + getopt/getopt_static.vcxproj \ + getopt/getopt_static.vcxproj.filters \ + grabbag/Makefile.lite \ + grabbag/grabbag_static.vcproj \ + grabbag/grabbag_static.vcxproj \ + grabbag/grabbag_static.vcxproj.filters \ + replaygain_analysis/Makefile.lite \ + replaygain_analysis/replaygain_analysis_static.vcproj \ + replaygain_analysis/replaygain_analysis_static.vcxproj \ + replaygain_analysis/replaygain_analysis_static.vcxproj.filters \ + replaygain_synthesis/Makefile.lite \ + replaygain_synthesis/replaygain_synthesis_static.vcproj \ + replaygain_synthesis/replaygain_synthesis_static.vcxproj \ + replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters \ + utf8/Makefile.lite \ + utf8/charmaps.h \ + utf8/makemap.c \ + utf8/charset_test.c \ + utf8/utf8_static.vcproj \ + utf8/utf8_static.vcxproj \ + utf8/utf8_static.vcxproj.filters \ + win_utf8_io/Makefile.lite \ + win_utf8_io/win_utf8_io_static.vcproj \ + win_utf8_io/win_utf8_io_static.vcxproj \ + win_utf8_io/win_utf8_io_static.vcxproj.filters + + +noinst_LTLIBRARIES = \ + getopt/libgetopt.la \ + grabbag/libgrabbag.la \ + utf8/libutf8.la \ + $(libwin_utf8_io) \ + replaygain_analysis/libreplaygain_analysis.la \ + replaygain_synthesis/libreplaygain_synthesis.la + + +if OS_IS_WINDOWS +win_utf8_io_libwin_utf8_io_la_SOURCES = win_utf8_io/win_utf8_io.c +libwin_utf8_io = win_utf8_io/libwin_utf8_io.la +win_utf8_io_libwin_utf8_io_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -lm +else +win_utf8_io_libwin_utf8_io_la_SOURCES = +libwin_utf8_io = +endif + +getopt_libgetopt_la_SOURCES = getopt/getopt.c getopt/getopt1.c + +grabbag_libgrabbag_la_SOURCES = \ + grabbag/alloc.c \ + grabbag/cuesheet.c \ + grabbag/file.c \ + grabbag/picture.c \ + grabbag/replaygain.c \ + grabbag/seektable.c \ + grabbag/snprintf.c + +utf8_libutf8_la_SOURCES = \ + utf8/charset.c \ + utf8/charset.h \ + utf8/iconvert.c \ + utf8/iconvert.h \ + utf8/utf8.c + +replaygain_analysis_libreplaygain_analysis_la_SOURCES = replaygain_analysis/replaygain_analysis.c + +replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS = -I $(top_srcdir)/src/share/replaygain_synthesis/include +replaygain_synthesis_libreplaygain_synthesis_la_SOURCES = replaygain_synthesis/replaygain_synthesis.c + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" diff --git a/deps/flac-1.3.2/src/share/Makefile.in b/deps/flac-1.3.2/src/share/Makefile.in new file mode 100644 index 0000000..f0ea88f --- /dev/null +++ b/deps/flac-1.3.2/src/share/Makefile.in @@ -0,0 +1,892 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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@ + +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2002-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under different licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/share +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \ + $(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \ + $(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \ + $(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.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)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \ + $(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +getopt_libgetopt_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am_getopt_libgetopt_la_OBJECTS = getopt/getopt.lo getopt/getopt1.lo +getopt_libgetopt_la_OBJECTS = $(am_getopt_libgetopt_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +grabbag_libgrabbag_la_LIBADD = +am_grabbag_libgrabbag_la_OBJECTS = grabbag/alloc.lo \ + grabbag/cuesheet.lo grabbag/file.lo grabbag/picture.lo \ + grabbag/replaygain.lo grabbag/seektable.lo grabbag/snprintf.lo +grabbag_libgrabbag_la_OBJECTS = $(am_grabbag_libgrabbag_la_OBJECTS) +replaygain_analysis_libreplaygain_analysis_la_LIBADD = +am_replaygain_analysis_libreplaygain_analysis_la_OBJECTS = \ + replaygain_analysis/replaygain_analysis.lo +replaygain_analysis_libreplaygain_analysis_la_OBJECTS = \ + $(am_replaygain_analysis_libreplaygain_analysis_la_OBJECTS) +replaygain_synthesis_libreplaygain_synthesis_la_LIBADD = +am_replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS = replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo +replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS = \ + $(am_replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS) +replaygain_synthesis_libreplaygain_synthesis_la_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) \ + $(replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +utf8_libutf8_la_LIBADD = +am_utf8_libutf8_la_OBJECTS = utf8/charset.lo utf8/iconvert.lo \ + utf8/utf8.lo +utf8_libutf8_la_OBJECTS = $(am_utf8_libutf8_la_OBJECTS) +@OS_IS_WINDOWS_TRUE@win_utf8_io_libwin_utf8_io_la_DEPENDENCIES = \ +@OS_IS_WINDOWS_TRUE@ $(top_builddir)/src/libFLAC/libFLAC.la +am__win_utf8_io_libwin_utf8_io_la_SOURCES_DIST = \ + win_utf8_io/win_utf8_io.c +@OS_IS_WINDOWS_TRUE@am_win_utf8_io_libwin_utf8_io_la_OBJECTS = \ +@OS_IS_WINDOWS_TRUE@ win_utf8_io/win_utf8_io.lo +win_utf8_io_libwin_utf8_io_la_OBJECTS = \ + $(am_win_utf8_io_libwin_utf8_io_la_OBJECTS) +@OS_IS_WINDOWS_TRUE@am_win_utf8_io_libwin_utf8_io_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__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_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(getopt_libgetopt_la_SOURCES) \ + $(grabbag_libgrabbag_la_SOURCES) \ + $(replaygain_analysis_libreplaygain_analysis_la_SOURCES) \ + $(replaygain_synthesis_libreplaygain_synthesis_la_SOURCES) \ + $(utf8_libutf8_la_SOURCES) \ + $(win_utf8_io_libwin_utf8_io_la_SOURCES) +DIST_SOURCES = $(getopt_libgetopt_la_SOURCES) \ + $(grabbag_libgrabbag_la_SOURCES) \ + $(replaygain_analysis_libreplaygain_analysis_la_SOURCES) \ + $(replaygain_synthesis_libreplaygain_synthesis_la_SOURCES) \ + $(utf8_libutf8_la_SOURCES) \ + $(am__win_utf8_io_libwin_utf8_io_la_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLAC__HAS_OGG = @FLAC__HAS_OGG@ +FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@ +FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@ +GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@ +GCC_MINOR_VERSION = @GCC_MINOR_VERSION@ +GCC_VERSION = @GCC_VERSION@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NASM = @NASM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OBJ_FORMAT = @OBJ_FORMAT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OGG_PACKAGE = @OGG_PACKAGE@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMMS_CFLAGS = @XMMS_CFLAGS@ +XMMS_CONFIG = @XMMS_CONFIG@ +XMMS_DATA_DIR = @XMMS_DATA_DIR@ +XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@ +XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@ +XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@ +XMMS_LIBS = @XMMS_LIBS@ +XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@ +XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@ +XMMS_VERSION = @XMMS_VERSION@ +XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@ +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_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = subdir-objects +AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include +EXTRA_DIST = \ + Makefile.lite \ + README \ + getopt/Makefile.lite \ + getopt/getopt_static.vcproj \ + getopt/getopt_static.vcxproj \ + getopt/getopt_static.vcxproj.filters \ + grabbag/Makefile.lite \ + grabbag/grabbag_static.vcproj \ + grabbag/grabbag_static.vcxproj \ + grabbag/grabbag_static.vcxproj.filters \ + replaygain_analysis/Makefile.lite \ + replaygain_analysis/replaygain_analysis_static.vcproj \ + replaygain_analysis/replaygain_analysis_static.vcxproj \ + replaygain_analysis/replaygain_analysis_static.vcxproj.filters \ + replaygain_synthesis/Makefile.lite \ + replaygain_synthesis/replaygain_synthesis_static.vcproj \ + replaygain_synthesis/replaygain_synthesis_static.vcxproj \ + replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters \ + utf8/Makefile.lite \ + utf8/charmaps.h \ + utf8/makemap.c \ + utf8/charset_test.c \ + utf8/utf8_static.vcproj \ + utf8/utf8_static.vcxproj \ + utf8/utf8_static.vcxproj.filters \ + win_utf8_io/Makefile.lite \ + win_utf8_io/win_utf8_io_static.vcproj \ + win_utf8_io/win_utf8_io_static.vcxproj \ + win_utf8_io/win_utf8_io_static.vcxproj.filters + +noinst_LTLIBRARIES = \ + getopt/libgetopt.la \ + grabbag/libgrabbag.la \ + utf8/libutf8.la \ + $(libwin_utf8_io) \ + replaygain_analysis/libreplaygain_analysis.la \ + replaygain_synthesis/libreplaygain_synthesis.la + +@OS_IS_WINDOWS_FALSE@win_utf8_io_libwin_utf8_io_la_SOURCES = +@OS_IS_WINDOWS_TRUE@win_utf8_io_libwin_utf8_io_la_SOURCES = win_utf8_io/win_utf8_io.c +@OS_IS_WINDOWS_FALSE@libwin_utf8_io = +@OS_IS_WINDOWS_TRUE@libwin_utf8_io = win_utf8_io/libwin_utf8_io.la +@OS_IS_WINDOWS_TRUE@win_utf8_io_libwin_utf8_io_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -lm +getopt_libgetopt_la_SOURCES = getopt/getopt.c getopt/getopt1.c +grabbag_libgrabbag_la_SOURCES = \ + grabbag/alloc.c \ + grabbag/cuesheet.c \ + grabbag/file.c \ + grabbag/picture.c \ + grabbag/replaygain.c \ + grabbag/seektable.c \ + grabbag/snprintf.c + +utf8_libutf8_la_SOURCES = \ + utf8/charset.c \ + utf8/charset.h \ + utf8/iconvert.c \ + utf8/iconvert.h \ + utf8/utf8.c + +replaygain_analysis_libreplaygain_analysis_la_SOURCES = replaygain_analysis/replaygain_analysis.c +replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS = -I $(top_srcdir)/src/share/replaygain_synthesis/include +replaygain_synthesis_libreplaygain_synthesis_la_SOURCES = replaygain_synthesis/replaygain_synthesis.c +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/share/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/share/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)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +getopt/$(am__dirstamp): + @$(MKDIR_P) getopt + @: > getopt/$(am__dirstamp) +getopt/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) getopt/$(DEPDIR) + @: > getopt/$(DEPDIR)/$(am__dirstamp) +getopt/getopt.lo: getopt/$(am__dirstamp) \ + getopt/$(DEPDIR)/$(am__dirstamp) +getopt/getopt1.lo: getopt/$(am__dirstamp) \ + getopt/$(DEPDIR)/$(am__dirstamp) + +getopt/libgetopt.la: $(getopt_libgetopt_la_OBJECTS) $(getopt_libgetopt_la_DEPENDENCIES) $(EXTRA_getopt_libgetopt_la_DEPENDENCIES) getopt/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(getopt_libgetopt_la_OBJECTS) $(getopt_libgetopt_la_LIBADD) $(LIBS) +grabbag/$(am__dirstamp): + @$(MKDIR_P) grabbag + @: > grabbag/$(am__dirstamp) +grabbag/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) grabbag/$(DEPDIR) + @: > grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/alloc.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/cuesheet.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/file.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/picture.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/replaygain.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/seektable.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) +grabbag/snprintf.lo: grabbag/$(am__dirstamp) \ + grabbag/$(DEPDIR)/$(am__dirstamp) + +grabbag/libgrabbag.la: $(grabbag_libgrabbag_la_OBJECTS) $(grabbag_libgrabbag_la_DEPENDENCIES) $(EXTRA_grabbag_libgrabbag_la_DEPENDENCIES) grabbag/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(grabbag_libgrabbag_la_OBJECTS) $(grabbag_libgrabbag_la_LIBADD) $(LIBS) +replaygain_analysis/$(am__dirstamp): + @$(MKDIR_P) replaygain_analysis + @: > replaygain_analysis/$(am__dirstamp) +replaygain_analysis/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) replaygain_analysis/$(DEPDIR) + @: > replaygain_analysis/$(DEPDIR)/$(am__dirstamp) +replaygain_analysis/replaygain_analysis.lo: \ + replaygain_analysis/$(am__dirstamp) \ + replaygain_analysis/$(DEPDIR)/$(am__dirstamp) + +replaygain_analysis/libreplaygain_analysis.la: $(replaygain_analysis_libreplaygain_analysis_la_OBJECTS) $(replaygain_analysis_libreplaygain_analysis_la_DEPENDENCIES) $(EXTRA_replaygain_analysis_libreplaygain_analysis_la_DEPENDENCIES) replaygain_analysis/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(replaygain_analysis_libreplaygain_analysis_la_OBJECTS) $(replaygain_analysis_libreplaygain_analysis_la_LIBADD) $(LIBS) +replaygain_synthesis/$(am__dirstamp): + @$(MKDIR_P) replaygain_synthesis + @: > replaygain_synthesis/$(am__dirstamp) +replaygain_synthesis/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) replaygain_synthesis/$(DEPDIR) + @: > replaygain_synthesis/$(DEPDIR)/$(am__dirstamp) +replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo: \ + replaygain_synthesis/$(am__dirstamp) \ + replaygain_synthesis/$(DEPDIR)/$(am__dirstamp) + +replaygain_synthesis/libreplaygain_synthesis.la: $(replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS) $(replaygain_synthesis_libreplaygain_synthesis_la_DEPENDENCIES) $(EXTRA_replaygain_synthesis_libreplaygain_synthesis_la_DEPENDENCIES) replaygain_synthesis/$(am__dirstamp) + $(AM_V_CCLD)$(replaygain_synthesis_libreplaygain_synthesis_la_LINK) $(replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS) $(replaygain_synthesis_libreplaygain_synthesis_la_LIBADD) $(LIBS) +utf8/$(am__dirstamp): + @$(MKDIR_P) utf8 + @: > utf8/$(am__dirstamp) +utf8/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) utf8/$(DEPDIR) + @: > utf8/$(DEPDIR)/$(am__dirstamp) +utf8/charset.lo: utf8/$(am__dirstamp) utf8/$(DEPDIR)/$(am__dirstamp) +utf8/iconvert.lo: utf8/$(am__dirstamp) utf8/$(DEPDIR)/$(am__dirstamp) +utf8/utf8.lo: utf8/$(am__dirstamp) utf8/$(DEPDIR)/$(am__dirstamp) + +utf8/libutf8.la: $(utf8_libutf8_la_OBJECTS) $(utf8_libutf8_la_DEPENDENCIES) $(EXTRA_utf8_libutf8_la_DEPENDENCIES) utf8/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(utf8_libutf8_la_OBJECTS) $(utf8_libutf8_la_LIBADD) $(LIBS) +win_utf8_io/$(am__dirstamp): + @$(MKDIR_P) win_utf8_io + @: > win_utf8_io/$(am__dirstamp) +win_utf8_io/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) win_utf8_io/$(DEPDIR) + @: > win_utf8_io/$(DEPDIR)/$(am__dirstamp) +win_utf8_io/win_utf8_io.lo: win_utf8_io/$(am__dirstamp) \ + win_utf8_io/$(DEPDIR)/$(am__dirstamp) + +win_utf8_io/libwin_utf8_io.la: $(win_utf8_io_libwin_utf8_io_la_OBJECTS) $(win_utf8_io_libwin_utf8_io_la_DEPENDENCIES) $(EXTRA_win_utf8_io_libwin_utf8_io_la_DEPENDENCIES) win_utf8_io/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(am_win_utf8_io_libwin_utf8_io_la_rpath) $(win_utf8_io_libwin_utf8_io_la_OBJECTS) $(win_utf8_io_libwin_utf8_io_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f getopt/*.$(OBJEXT) + -rm -f getopt/*.lo + -rm -f grabbag/*.$(OBJEXT) + -rm -f grabbag/*.lo + -rm -f replaygain_analysis/*.$(OBJEXT) + -rm -f replaygain_analysis/*.lo + -rm -f replaygain_synthesis/*.$(OBJEXT) + -rm -f replaygain_synthesis/*.lo + -rm -f utf8/*.$(OBJEXT) + -rm -f utf8/*.lo + -rm -f win_utf8_io/*.$(OBJEXT) + -rm -f win_utf8_io/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@getopt/$(DEPDIR)/getopt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@getopt/$(DEPDIR)/getopt1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/cuesheet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/file.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/picture.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/replaygain.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/seektable.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/snprintf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@replaygain_analysis/$(DEPDIR)/replaygain_analysis.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utf8/$(DEPDIR)/charset.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utf8/$(DEPDIR)/iconvert.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utf8/$(DEPDIR)/utf8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@win_utf8_io/$(DEPDIR)/win_utf8_io.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 $@ $< + +replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo: replaygain_synthesis/replaygain_synthesis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS) $(CFLAGS) -MT replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo -MD -MP -MF replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Tpo -c -o replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo `test -f 'replaygain_synthesis/replaygain_synthesis.c' || echo '$(srcdir)/'`replaygain_synthesis/replaygain_synthesis.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Tpo replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='replaygain_synthesis/replaygain_synthesis.c' object='replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS) $(CFLAGS) -c -o replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo `test -f 'replaygain_synthesis/replaygain_synthesis.c' || echo '$(srcdir)/'`replaygain_synthesis/replaygain_synthesis.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf getopt/.libs getopt/_libs + -rm -rf grabbag/.libs grabbag/_libs + -rm -rf replaygain_analysis/.libs replaygain_analysis/_libs + -rm -rf replaygain_synthesis/.libs replaygain_synthesis/_libs + -rm -rf utf8/.libs utf8/_libs + -rm -rf win_utf8_io/.libs win_utf8_io/_libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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) +installdirs: +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) + -rm -f getopt/$(DEPDIR)/$(am__dirstamp) + -rm -f getopt/$(am__dirstamp) + -rm -f grabbag/$(DEPDIR)/$(am__dirstamp) + -rm -f grabbag/$(am__dirstamp) + -rm -f replaygain_analysis/$(DEPDIR)/$(am__dirstamp) + -rm -f replaygain_analysis/$(am__dirstamp) + -rm -f replaygain_synthesis/$(DEPDIR)/$(am__dirstamp) + -rm -f replaygain_synthesis/$(am__dirstamp) + -rm -f utf8/$(DEPDIR)/$(am__dirstamp) + -rm -f utf8/$(am__dirstamp) + -rm -f win_utf8_io/$(DEPDIR)/$(am__dirstamp) + -rm -f win_utf8_io/$(am__dirstamp) + +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 getopt/$(DEPDIR) grabbag/$(DEPDIR) replaygain_analysis/$(DEPDIR) replaygain_synthesis/$(DEPDIR) utf8/$(DEPDIR) win_utf8_io/$(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-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 getopt/$(DEPDIR) grabbag/$(DEPDIR) replaygain_analysis/$(DEPDIR) replaygain_synthesis/$(DEPDIR) utf8/$(DEPDIR) win_utf8_io/$(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: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/deps/flac-1.3.2/src/share/Makefile.lite b/deps/flac-1.3.2/src/share/Makefile.lite new file mode 100644 index 0000000..d577787 --- /dev/null +++ b/deps/flac-1.3.2/src/share/Makefile.lite @@ -0,0 +1,58 @@ +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2001-2009 Josh Coalson +# Copyright (C) 2011-2016 Xiph.Org Foundation +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under different licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. + +.PHONY: all getopt grabbag replaygain_analysis replaygain_synthesis utf8 +all: getopt replaygain_analysis grabbag replaygain_synthesis utf8 + +DEFAULT_CONFIG = release + +CONFIG = $(DEFAULT_CONFIG) + +debug : CONFIG = debug +valgrind: CONFIG = valgrind +release : CONFIG = release + +debug : all +valgrind: all +release : all + +getopt: + (cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +replaygain_analysis: + (cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +grabbag: + (cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +replaygain_synthesis: + (cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +utf8: + (cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +win_utf8_io: + (cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +clean: + -(cd getopt ; $(MAKE) -f Makefile.lite clean) + -(cd grabbag ; $(MAKE) -f Makefile.lite clean) + -(cd replaygain_analysis ; $(MAKE) -f Makefile.lite clean) + -(cd replaygain_synthesis ; $(MAKE) -f Makefile.lite clean) + -(cd utf8 ; $(MAKE) -f Makefile.lite clean) + -(cd win_utf8_io ; $(MAKE) -f Makefile.lite clean) diff --git a/deps/flac-1.3.2/src/share/README b/deps/flac-1.3.2/src/share/README new file mode 100644 index 0000000..1d4fede --- /dev/null +++ b/deps/flac-1.3.2/src/share/README @@ -0,0 +1,5 @@ +This directory contains several convenience libraries used by the rest of the +tools and plugins. Two of them (getopt and utf8) are shamelessly copied from +vorbistools, one for manipulating UTF-8 strings (GPL) and one for implementing +getopt (LGPL). libFLAC does not link to either; the only FLAC tools that do +are GPL'ed. diff --git a/deps/flac-1.3.2/src/share/getopt/Makefile.lite b/deps/flac-1.3.2/src/share/getopt/Makefile.lite new file mode 100644 index 0000000..b4df6ec --- /dev/null +++ b/deps/flac-1.3.2/src/share/getopt/Makefile.lite @@ -0,0 +1,16 @@ +# +# GNU makefile +# + +topdir = ../../.. + +LIB_NAME = libgetopt +INCLUDES = -I$(topdir)/include + +SRCS_C = \ + getopt.c \ + getopt1.c + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/share/getopt/getopt.c b/deps/flac-1.3.2/src/share/getopt/getopt.c new file mode 100644 index 0000000..e8a13aa --- /dev/null +++ b/deps/flac-1.3.2/src/share/getopt/getopt.c @@ -0,0 +1,1063 @@ +/* + NOTE: + I cannot get the vanilla getopt code to work (i.e. compile only what + is needed and not duplicate symbols found in the standard library) + on all the platforms that FLAC supports. In particular the gating + of code with the ELIDE_CODE #define is not accurate enough on systems + that are POSIX but not glibc. If someone has a patch that works on + GNU/Linux, Darwin, AND Solaris please submit it on the project page: + https://sourceforge.net/p/flac/patches/ + + In the meantime I have munged the global symbols and removed gates + around code, while at the same time trying to touch the original as + little as possible. +*/ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include <gnu-versions.h> +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#if 1 +/*[JEC] was:#ifndef ELIDE_CODE*/ + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include <stdlib.h> +# include <unistd.h> +#endif /* GNU C library. */ + +#ifdef VMS +# include <unixlib.h> +# if HAVE_STRING_H - 0 +# include <string.h> +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include <libintl.h> +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `share__getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `share__getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "share/getopt.h" +/*[JEC] was:#include "getopt.h"*/ + +/* For communication from `share__getopt' to the caller. + When `share__getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *share__optarg = 0; /*[JEC] initialize to avoid being a 'Common' symbol */ + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `share__getopt'. + + On entry to `share__getopt', zero means this is the first call; initialize. + + When `share__getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `share__optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int share__optind = 1; + +/* Formerly, initialization of getopt depended on share__optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +static int share____getopt_initialized = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int share__opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int share__optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `share__getopt' to return -1 with `share__optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include <string.h> +# define my_index strchr +#else + +#include <string.h> + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (const char * name); +#endif + +static char * +my_index (const char *str, int chr) +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,share__optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = share__optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (share__optind - last_nonopt); + last_nonopt = share__optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *share___getopt_initialize (int, char *const *, const char *); +#endif +static const char * +share___getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = share__optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#else + (void)argc, (void)argv; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `share__getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `share__getopt' finds another option character, it returns that character, + updating `share__optind' and `nextchar' so that the next call to `share__getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `share__getopt' returns -1. + Then `share__optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `share__opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `share__optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `share__optarg', otherwise `share__optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `share__getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct share__option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +share___getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct share__option *longopts; + int *longind; + int long_only; +{ + share__optarg = NULL; + + if (share__optind == 0 || !share____getopt_initialized) + { + if (share__optind == 0) + share__optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = share___getopt_initialize (argc, argv, optstring); + share____getopt_initialized = 1; + } + + /* Test whether ARGV[share__optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[share__optind][0] != '-' || argv[share__optind][1] == '\0' \ + || (share__optind < nonoption_flags_len \ + && __getopt_nonoption_flags[share__optind] == '1')) +#else +# define NONOPTION_P (argv[share__optind][0] != '-' || argv[share__optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > share__optind) + last_nonopt = share__optind; + if (first_nonopt > share__optind) + first_nonopt = share__optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != share__optind) + exchange ((char **) argv); + else if (last_nonopt != share__optind) + first_nonopt = share__optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (share__optind < argc && NONOPTION_P) + share__optind++; + last_nonopt = share__optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (share__optind != argc && !strcmp (argv[share__optind], "--")) + { + share__optind++; + + if (first_nonopt != last_nonopt && last_nonopt != share__optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = share__optind; + last_nonopt = argc; + + share__optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (share__optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + share__optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + share__optarg = argv[share__optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[share__optind] + 1 + + (longopts != NULL && argv[share__optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[share__optind][1] == '-' + || (long_only && (argv[share__optind][2] || !my_index (optstring, argv[share__optind][1]))))) + { + char *nameend; + const struct share__option *p; + const struct share__option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (share__opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[share__optind]); + nextchar += strlen (nextchar); + share__optind++; + share__optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + share__optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + share__optarg = nameend + 1; + else + { + if (share__opterr) + { + if (argv[share__optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[share__optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + share__optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (share__optind < argc) + share__optarg = argv[share__optind++]; + else + { + if (share__opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[share__optind - 1]); + nextchar += strlen (nextchar); + share__optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not share__getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[share__optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (share__opterr) + { + if (argv[share__optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[share__optind][0], nextchar); + } + nextchar = (char *) ""; + share__optind++; + share__optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `share__optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++share__optind; + + if (temp == NULL || c == ':') + { + if (share__opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + share__optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct share__option *p; + const struct share__option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + share__optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + share__optind++; + } + else if (share__optind == argc) + { + if (share__opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + share__optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `share__optind' once; + increment it again when taking next ARGV-elt as argument. */ + share__optarg = argv[share__optind++]; + + /* share__optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = share__optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (share__opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[share__optind]); + nextchar += strlen (nextchar); + share__optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + share__optarg = nameend + 1; + else + { + if (share__opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (share__optind < argc) + share__optarg = argv[share__optind++]; + else + { + if (share__opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[share__optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + share__optarg = nextchar; + share__optind++; + } + else + share__optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + share__optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + share__optind++; + } + else if (share__optind == argc) + { + if (share__opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + share__optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `share__optind' once; + increment it again when taking next ARGV-elt as argument. */ + share__optarg = argv[share__optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +share__getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return share___getopt_internal (argc, argv, optstring, + (const struct share__option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `share__getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = share__optind ? share__optind : 1; + + c = share__getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", share__optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (share__optind < argc) + { + printf ("non-option ARGV-elements: "); + while (share__optind < argc) + printf ("%s ", argv[share__optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/deps/flac-1.3.2/src/share/getopt/getopt1.c b/deps/flac-1.3.2/src/share/getopt/getopt1.c new file mode 100644 index 0000000..740e498 --- /dev/null +++ b/deps/flac-1.3.2/src/share/getopt/getopt1.c @@ -0,0 +1,204 @@ +/* + NOTE: + I cannot get the vanilla getopt code to work (i.e. compile only what + is needed and not duplicate symbols found in the standard library) + on all the platforms that FLAC supports. In particular the gating + of code with the ELIDE_CODE #define is not accurate enough on systems + that are POSIX but not glibc. If someone has a patch that works on + GNU/Linux, Darwin, AND Solaris please submit it on the project page: + https://sourceforge.net/p/flac/patches/ + + In the meantime I have munged the global symbols and removed gates + around code, while at the same time trying to touch the original as + little as possible. +*/ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "share/getopt.h" +/*[JEC] was:#include "getopt.h"*/ + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include <gnu-versions.h> +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#if 1 +/*[JEC] was:#ifndef ELIDE_CODE*/ + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +share__getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct share__option *long_options; + int *opt_index; +{ + return share___getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like share__getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +share__getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct share__option *long_options; + int *opt_index; +{ + return share___getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include <stdio.h> + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = share__optind ? share__optind : 1; + int option_index = 0; + static struct share__option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = share__getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (share__optarg) + printf (" with arg %s", share__optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", share__optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", share__optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (share__optind < argc) + { + printf ("non-option ARGV-elements: "); + while (share__optind < argc) + printf ("%s ", argv[share__optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/deps/flac-1.3.2/src/share/getopt/getopt_static.vcproj b/deps/flac-1.3.2/src/share/getopt/getopt_static.vcproj new file mode 100644 index 0000000..7a95af2 --- /dev/null +++ b/deps/flac-1.3.2/src/share/getopt/getopt_static.vcproj @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="getopt_static"
+ ProjectGUID="{4cefbc80-c215-11db-8314-0800200c9a66}"
+ RootNamespace="getopt_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\getopt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\getopt1.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\..\include\share\getopt.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/share/getopt/getopt_static.vcxproj b/deps/flac-1.3.2/src/share/getopt/getopt_static.vcxproj new file mode 100644 index 0000000..d536824 --- /dev/null +++ b/deps/flac-1.3.2/src/share/getopt/getopt_static.vcxproj @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc80-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>getopt_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="getopt.c" />
+ <ClCompile Include="getopt1.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\getopt.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/getopt/getopt_static.vcxproj.filters b/deps/flac-1.3.2/src/share/getopt/getopt_static.vcxproj.filters new file mode 100644 index 0000000..b528a7d --- /dev/null +++ b/deps/flac-1.3.2/src/share/getopt/getopt_static.vcxproj.filters @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{98dc8c56-677d-4f5b-9c7e-031634c635f0}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="getopt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="getopt1.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\getopt.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/grabbag/Makefile.lite b/deps/flac-1.3.2/src/share/grabbag/Makefile.lite new file mode 100644 index 0000000..6c8ff6c --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/Makefile.lite @@ -0,0 +1,30 @@ +# grabbag - Convenience lib for various routines common to several tools + +# +# GNU makefile +# + +topdir = ../../.. +libdir = $(topdir)/objs/$(BUILD)/lib + +ifeq ($(OS),Darwin) + EXPLICIT_LIBS = $(libdir)/libFLAC.a $(libdir)/libreplaygain_analysis.a $(OGG_EXPLICIT_LIBS) -lm +else + LIBS = -lFLAC -lreplaygain_analysis $(OGG_LIBS) -lm +endif + +LIB_NAME = libgrabbag +INCLUDES = -I$(topdir)/include + +SRCS_C = \ + alloc.c \ + cuesheet.c \ + file.c \ + picture.c \ + replaygain.c \ + seektable.c \ + snprintf.c + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/share/grabbag/alloc.c b/deps/flac-1.3.2/src/share/grabbag/alloc.c new file mode 100644 index 0000000..82a77b1 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/alloc.c @@ -0,0 +1,48 @@ +/* alloc - Convenience routines for safely allocating memory + * Copyright (C) 2007-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> + +#include "share/alloc.h" + +void *safe_malloc_mul_2op_(size_t size1, size_t size2) +{ + if(!size1 || !size2) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(size1 > SIZE_MAX / size2) + return 0; + return malloc(size1*size2); +} diff --git a/deps/flac-1.3.2/src/share/grabbag/cuesheet.c b/deps/flac-1.3.2/src/share/grabbag/cuesheet.c new file mode 100644 index 0000000..78473d8 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/cuesheet.c @@ -0,0 +1,656 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "FLAC/assert.h" +#include "share/compat.h" +#include "share/grabbag.h" +#include "share/safe_str.h" + +unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames) +{ + return ((minutes * 60) + seconds) * 75 + frames; +} + +void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames) +{ + *frames = frame % 75; + frame /= 75; + *seconds = frame % 60; + frame /= 60; + *minutes = frame; +} + +/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */ +static int local__parse_int_(const char *s) +{ + int ret = 0; + char c; + + if(*s == '\0') + return -1; + + while('\0' != (c = *s++)) + if(c >= '0' && c <= '9') + ret = ret * 10 + (c - '0'); + else + return -1; + + return ret; +} + +/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */ +static FLAC__int64 local__parse_int64_(const char *s) +{ + FLAC__int64 ret = 0; + char c; + + if(*s == '\0') + return -1; + + while('\0' != (c = *s++)) + if(c >= '0' && c <= '9') + ret = ret * 10 + (c - '0'); + else + return -1; + + return ret; +} + +/* accept minute:second:frame syntax of '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67 + * return sample number or <0 for error + * WATCHOUT: if sample rate is not evenly divisible by 75, the resulting sample number will be approximate + */ +static FLAC__int64 local__parse_msf_(const char *s, unsigned sample_rate) +{ + FLAC__int64 ret, field; + char c; + + c = *s++; + if(c >= '0' && c <= '9') + field = (c - '0'); + else + return -1; + while(':' != (c = *s++)) { + if(c >= '0' && c <= '9') + field = field * 10 + (c - '0'); + else + return -1; + } + + ret = field * 60 * sample_rate; + + c = *s++; + if(c >= '0' && c <= '9') + field = (c - '0'); + else + return -1; + if(':' != (c = *s++)) { + if(c >= '0' && c <= '9') { + field = field * 10 + (c - '0'); + c = *s++; + if(c != ':') + return -1; + } + else + return -1; + } + + if(field >= 60) + return -1; + + ret += field * sample_rate; + + c = *s++; + if(c >= '0' && c <= '9') + field = (c - '0'); + else + return -1; + if('\0' != (c = *s++)) { + if(c >= '0' && c <= '9') { + field = field * 10 + (c - '0'); + c = *s++; + } + else + return -1; + } + + if(c != '\0') + return -1; + + if(field >= 75) + return -1; + + ret += field * (sample_rate / 75); + + return ret; +} + +/* accept minute:second syntax of '[0-9]+:[0-9][0-9]?{,.[0-9]+}', but second < 60, e.g. 0:0.0, 3:5, 15:31.731 + * return sample number or <0 for error + * WATCHOUT: depending on the sample rate, the resulting sample number may be approximate with fractional seconds + */ +static FLAC__int64 local__parse_ms_(const char *s, unsigned sample_rate) +{ + FLAC__int64 ret, field; + double x; + char c, *end; + + c = *s++; + if(c >= '0' && c <= '9') + field = (c - '0'); + else + return -1; + while(':' != (c = *s++)) { + if(c >= '0' && c <= '9') + field = field * 10 + (c - '0'); + else + return -1; + } + + ret = field * 60 * sample_rate; + + s++; /* skip the ':' */ + if(strspn(s, "0123456789.") != strlen(s)) + return -1; + x = strtod(s, &end); + if(*end || end == s) + return -1; + if(x < 0.0 || x >= 60.0) + return -1; + + ret += (FLAC__int64)(x * sample_rate); + + return ret; +} + +static char *local__get_field_(char **s, FLAC__bool allow_quotes) +{ + FLAC__bool has_quote = false; + char *p; + + FLAC__ASSERT(0 != s); + + if(0 == *s) + return 0; + + /* skip leading whitespace */ + while(**s && 0 != strchr(" \t\r\n", **s)) + (*s)++; + + if(**s == 0) { + *s = 0; + return 0; + } + + if(allow_quotes && (**s == '"')) { + has_quote = true; + (*s)++; + if(**s == 0) { + *s = 0; + return 0; + } + } + + p = *s; + + if(has_quote) { + *s = strchr(*s, '\"'); + /* if there is no matching end quote, it's an error */ + if(0 == *s) + p = *s = 0; + else { + **s = '\0'; + (*s)++; + } + } + else { + while(**s && 0 == strchr(" \t\r\n", **s)) + (*s)++; + if(**s) { + **s = '\0'; + (*s)++; + } + else + *s = 0; + } + + return p; +} + +static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset) +{ + char buffer[4096], *line, *field; + unsigned forced_leadout_track_num = 0; + FLAC__uint64 forced_leadout_track_offset = 0; + int in_track_num = -1, in_index_num = -1; + FLAC__bool disc_has_catalog = false, track_has_flags = false, track_has_isrc = false, has_forced_leadout = false; + FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet; + + FLAC__ASSERT(!is_cdda || sample_rate == 44100); + /* double protection */ + if(is_cdda && sample_rate != 44100) { + *error_message = "CD-DA cuesheet only allowed with 44.1kHz sample rate"; + return false; + } + + cs->lead_in = is_cdda? 2 * 44100 /* The default lead-in size for CD-DA */ : 0; + cs->is_cd = is_cdda; + + while(0 != fgets(buffer, sizeof(buffer), file)) { + (*last_line_read)++; + line = buffer; + + { + size_t linelen = strlen(line); + if((linelen == sizeof(buffer)-1) && line[linelen-1] != '\n') { + *error_message = "line too long"; + return false; + } + } + + if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) { + if(0 == FLAC__STRCASECMP(field, "CATALOG")) { + if(disc_has_catalog) { + *error_message = "found multiple CATALOG commands"; + return false; + } + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) { + *error_message = "CATALOG is missing catalog number"; + return false; + } + if(strlen(field) >= sizeof(cs->media_catalog_number)) { + *error_message = "CATALOG number is too long"; + return false; + } + if(is_cdda && (strlen(field) != 13 || strspn(field, "0123456789") != 13)) { + *error_message = "CD-DA CATALOG number must be 13 decimal digits"; + return false; + } + safe_strncpy(cs->media_catalog_number, field, sizeof(cs->media_catalog_number)); + disc_has_catalog = true; + } + else if(0 == FLAC__STRCASECMP(field, "FLAGS")) { + if(track_has_flags) { + *error_message = "found multiple FLAGS commands"; + return false; + } + if(in_track_num < 0 || in_index_num >= 0) { + *error_message = "FLAGS command must come after TRACK but before INDEX"; + return false; + } + while(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) { + if(0 == FLAC__STRCASECMP(field, "PRE")) + cs->tracks[cs->num_tracks-1].pre_emphasis = 1; + } + track_has_flags = true; + } + else if(0 == FLAC__STRCASECMP(field, "INDEX")) { + FLAC__int64 xx; + FLAC__StreamMetadata_CueSheet_Track *track = &cs->tracks[cs->num_tracks-1]; + if(in_track_num < 0) { + *error_message = "found INDEX before any TRACK"; + return false; + } + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "INDEX is missing index number"; + return false; + } + in_index_num = local__parse_int_(field); + if(in_index_num < 0) { + *error_message = "INDEX has invalid index number"; + return false; + } + FLAC__ASSERT(cs->num_tracks > 0); + if(track->num_indices == 0) { + /* it's the first index point of the track */ + if(in_index_num > 1) { + *error_message = "first INDEX number of a TRACK must be 0 or 1"; + return false; + } + } + else { + if(in_index_num != track->indices[track->num_indices-1].number + 1) { + *error_message = "INDEX numbers must be sequential"; + return false; + } + } + if(is_cdda && in_index_num > 99) { + *error_message = "CD-DA INDEX number must be between 0 and 99, inclusive"; + return false; + } + /*@@@ search for duplicate track number? */ + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "INDEX is missing an offset after the index number"; + return false; + } + /* first parse as minute:second:frame format */ + xx = local__parse_msf_(field, sample_rate); + if(xx < 0) { + /* CD-DA must use only MM:SS:FF format */ + if(is_cdda) { + *error_message = "illegal INDEX offset (not of the form MM:SS:FF)"; + return false; + } + /* as an extension for non-CD-DA we allow MM:SS.SS or raw sample number */ + xx = local__parse_ms_(field, sample_rate); + if(xx < 0) { + xx = local__parse_int64_(field); + if(xx < 0) { + *error_message = "illegal INDEX offset"; + return false; + } + } + } + else if(sample_rate % 75 && xx) { + /* only sample zero is exact */ + *error_message = "illegal INDEX offset (MM:SS:FF form not allowed if sample rate is not a multiple of 75)"; + return false; + } + if(is_cdda && cs->num_tracks == 1 && cs->tracks[0].num_indices == 0 && xx != 0) { + *error_message = "first INDEX of first TRACK must have an offset of 00:00:00"; + return false; + } + if(is_cdda && track->num_indices > 0 && (FLAC__uint64)xx <= track->indices[track->num_indices-1].offset) { + *error_message = "CD-DA INDEX offsets must increase in time"; + return false; + } + /* fill in track offset if it's the first index of the track */ + if(track->num_indices == 0) + track->offset = (FLAC__uint64)xx; + if(is_cdda && cs->num_tracks > 1) { + const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-2]; + if((FLAC__uint64)xx <= prev->offset + prev->indices[prev->num_indices-1].offset) { + *error_message = "CD-DA INDEX offsets must increase in time"; + return false; + } + } + if(!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, cs->num_tracks-1, track->num_indices)) { + *error_message = "memory allocation error"; + return false; + } + track->indices[track->num_indices-1].offset = (FLAC__uint64)xx - track->offset; + track->indices[track->num_indices-1].number = in_index_num; + } + else if(0 == FLAC__STRCASECMP(field, "ISRC")) { + char *l, *r; + if(track_has_isrc) { + *error_message = "found multiple ISRC commands"; + return false; + } + if(in_track_num < 0 || in_index_num >= 0) { + *error_message = "ISRC command must come after TRACK but before INDEX"; + return false; + } + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) { + *error_message = "ISRC is missing ISRC number"; + return false; + } + /* strip out dashes */ + for(l = r = field; *r; r++) { + if(*r != '-') + *l++ = *r; + } + *l = '\0'; + if(strlen(field) != 12 || strspn(field, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") < 5 || strspn(field+5, "1234567890") != 7) { + *error_message = "invalid ISRC number"; + return false; + } + safe_strncpy(cs->tracks[cs->num_tracks-1].isrc, field, sizeof(cs->tracks[cs->num_tracks-1].isrc)); + track_has_isrc = true; + } + else if(0 == FLAC__STRCASECMP(field, "TRACK")) { + if(cs->num_tracks > 0) { + const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-1]; + if( + prev->num_indices == 0 || + ( + is_cdda && + ( + (prev->num_indices == 1 && prev->indices[0].number != 1) || + (prev->num_indices == 2 && prev->indices[0].number != 1 && prev->indices[1].number != 1) + ) + ) + ) { + *error_message = is_cdda? + "previous TRACK must specify at least one INDEX 01" : + "previous TRACK must specify at least one INDEX"; + return false; + } + } + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "TRACK is missing track number"; + return false; + } + in_track_num = local__parse_int_(field); + if(in_track_num < 0) { + *error_message = "TRACK has invalid track number"; + return false; + } + if(in_track_num == 0) { + *error_message = "TRACK number must be greater than 0"; + return false; + } + if(is_cdda) { + if(in_track_num > 99) { + *error_message = "CD-DA TRACK number must be between 1 and 99, inclusive"; + return false; + } + } + else { + if(in_track_num == 255) { + *error_message = "TRACK number 255 is reserved for the lead-out"; + return false; + } + else if(in_track_num > 255) { + *error_message = "TRACK number must be between 1 and 254, inclusive"; + return false; + } + } + if(is_cdda && cs->num_tracks > 0 && in_track_num != cs->tracks[cs->num_tracks-1].number + 1) { + *error_message = "CD-DA TRACK numbers must be sequential"; + return false; + } + /*@@@ search for duplicate track number? */ + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "TRACK is missing a track type after the track number"; + return false; + } + if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) { + *error_message = "memory allocation error"; + return false; + } + cs->tracks[cs->num_tracks-1].number = in_track_num; + cs->tracks[cs->num_tracks-1].type = (0 == FLAC__STRCASECMP(field, "AUDIO"))? 0 : 1; /*@@@ should we be more strict with the value here? */ + in_index_num = -1; + track_has_flags = false; + track_has_isrc = false; + } + else if(0 == FLAC__STRCASECMP(field, "REM")) { + if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) { + if(0 == strcmp(field, "FLAC__lead-in")) { + FLAC__int64 xx; + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "FLAC__lead-in is missing offset"; + return false; + } + xx = local__parse_int64_(field); + if(xx < 0) { + *error_message = "illegal FLAC__lead-in offset"; + return false; + } + if(is_cdda && xx % 588 != 0) { + *error_message = "illegal CD-DA FLAC__lead-in offset, must be even multiple of 588 samples"; + return false; + } + cs->lead_in = (FLAC__uint64)xx; + } + else if(0 == strcmp(field, "FLAC__lead-out")) { + int track_num; + FLAC__int64 offset; + if(has_forced_leadout) { + *error_message = "multiple FLAC__lead-out commands"; + return false; + } + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "FLAC__lead-out is missing track number"; + return false; + } + track_num = local__parse_int_(field); + if(track_num < 0) { + *error_message = "illegal FLAC__lead-out track number"; + return false; + } + forced_leadout_track_num = (unsigned)track_num; + /*@@@ search for duplicate track number? */ + if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) { + *error_message = "FLAC__lead-out is missing offset"; + return false; + } + offset = local__parse_int64_(field); + if(offset < 0) { + *error_message = "illegal FLAC__lead-out offset"; + return false; + } + forced_leadout_track_offset = (FLAC__uint64)offset; + if(forced_leadout_track_offset != lead_out_offset) { + *error_message = "FLAC__lead-out offset does not match end-of-stream offset"; + return false; + } + has_forced_leadout = true; + } + } + } + } + } + + if(cs->num_tracks == 0) { + *error_message = "there must be at least one TRACK command"; + return false; + } + else { + const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-1]; + if( + prev->num_indices == 0 || + ( + is_cdda && + ( + (prev->num_indices == 1 && prev->indices[0].number != 1) || + (prev->num_indices == 2 && prev->indices[0].number != 1 && prev->indices[1].number != 1) + ) + ) + ) { + *error_message = is_cdda? + "previous TRACK must specify at least one INDEX 01" : + "previous TRACK must specify at least one INDEX"; + return false; + } + } + + if(!has_forced_leadout) { + forced_leadout_track_num = is_cdda? 170 : 255; + forced_leadout_track_offset = lead_out_offset; + } + if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) { + *error_message = "memory allocation error"; + return false; + } + cs->tracks[cs->num_tracks-1].number = forced_leadout_track_num; + cs->tracks[cs->num_tracks-1].offset = forced_leadout_track_offset; + + if(!feof(file)) { + *error_message = "read error"; + return false; + } + return true; +} + +FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset) +{ + FLAC__StreamMetadata *cuesheet; + + FLAC__ASSERT(0 != file); + FLAC__ASSERT(0 != error_message); + FLAC__ASSERT(0 != last_line_read); + + *last_line_read = 0; + cuesheet = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET); + + if(0 == cuesheet) { + *error_message = "memory allocation error"; + return 0; + } + + if(!local__cuesheet_parse_(file, error_message, last_line_read, cuesheet, sample_rate, is_cdda, lead_out_offset)) { + FLAC__metadata_object_delete(cuesheet); + return 0; + } + + return cuesheet; +} + +void grabbag__cuesheet_emit(FILE *file, const FLAC__StreamMetadata *cuesheet, const char *file_reference) +{ + const FLAC__StreamMetadata_CueSheet *cs; + unsigned track_num, index_num; + + FLAC__ASSERT(0 != file); + FLAC__ASSERT(0 != cuesheet); + FLAC__ASSERT(cuesheet->type == FLAC__METADATA_TYPE_CUESHEET); + + cs = &cuesheet->data.cue_sheet; + + if(*(cs->media_catalog_number)) + fprintf(file, "CATALOG %s\n", cs->media_catalog_number); + fprintf(file, "FILE %s\n", file_reference); + + for(track_num = 0; track_num < cs->num_tracks-1; track_num++) { + const FLAC__StreamMetadata_CueSheet_Track *track = cs->tracks + track_num; + + fprintf(file, " TRACK %02u %s\n", (unsigned)track->number, track->type == 0? "AUDIO" : "DATA"); + + if(track->pre_emphasis) + fprintf(file, " FLAGS PRE\n"); + if(*(track->isrc)) + fprintf(file, " ISRC %s\n", track->isrc); + + for(index_num = 0; index_num < track->num_indices; index_num++) { + const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + index_num; + + fprintf(file, " INDEX %02u ", (unsigned)indx->number); + if(cs->is_cd) { + const unsigned logical_frame = (unsigned)((track->offset + indx->offset) / (44100 / 75)); + unsigned m, s, f; + grabbag__cuesheet_frame_to_msf(logical_frame, &m, &s, &f); + fprintf(file, "%02u:%02u:%02u\n", m, s, f); + } + else + fprintf(file, "%" PRIu64 "\n", (track->offset + indx->offset)); + } + } + + fprintf(file, "REM FLAC__lead-in %" PRIu64 "\n", cs->lead_in); + fprintf(file, "REM FLAC__lead-out %u %" PRIu64 "\n", (unsigned)cs->tracks[track_num].number, cs->tracks[track_num].offset); +} diff --git a/deps/flac-1.3.2/src/share/grabbag/file.c b/deps/flac-1.3.2/src/share/grabbag/file.c new file mode 100644 index 0000000..4cbef9d --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/file.c @@ -0,0 +1,193 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if defined _MSC_VER || defined __MINGW32__ +#include <sys/utime.h> /* for utime() */ +#include <io.h> /* for chmod(), _setmode(), unlink() */ +#include <fcntl.h> /* for _O_BINARY */ +#else +#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ +#include <utime.h> /* for utime() */ +#endif +#if defined __CYGWIN__ || defined __EMX__ +#include <io.h> /* for setmode(), O_BINARY */ +#include <fcntl.h> /* for _O_BINARY */ +#endif +#include <sys/stat.h> /* for stat(), maybe chmod() */ +#if defined _WIN32 && !defined __CYGWIN__ +#else +#include <unistd.h> /* for unlink() */ +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* for strrchr() */ +#if defined _WIN32 && !defined __CYGWIN__ +// for GetFileInformationByHandle() etc +#include <windows.h> +#include <winbase.h> +#endif +#include "share/grabbag.h" + + +void grabbag__file_copy_metadata(const char *srcpath, const char *destpath) +{ + struct flac_stat_s srcstat; + struct utimbuf srctime; + + if(0 == flac_stat(srcpath, &srcstat)) { + srctime.actime = srcstat.st_atime; + srctime.modtime = srcstat.st_mtime; + (void)flac_chmod(destpath, srcstat.st_mode); + (void)flac_utime(destpath, &srctime); + } +} + +FLAC__off_t grabbag__file_get_filesize(const char *srcpath) +{ + struct flac_stat_s srcstat; + + if(0 == flac_stat(srcpath, &srcstat)) + return srcstat.st_size; + else + return -1; +} + +const char *grabbag__file_get_basename(const char *srcpath) +{ + const char *p; + + p = strrchr(srcpath, '/'); + if(0 == p) { + p = strrchr(srcpath, '\\'); + if(0 == p) + return srcpath; + } + return ++p; +} + +FLAC__bool grabbag__file_change_stats(const char *filename, FLAC__bool read_only) +{ + struct flac_stat_s stats; + + if(0 == flac_stat(filename, &stats)) { +#if !defined _MSC_VER && !defined __MINGW32__ + if(read_only) { + stats.st_mode &= ~S_IWUSR; + stats.st_mode &= ~S_IWGRP; + stats.st_mode &= ~S_IWOTH; + } + else { + stats.st_mode |= S_IWUSR; + } +#else + if(read_only) + stats.st_mode &= ~S_IWRITE; + else + stats.st_mode |= S_IWRITE; +#endif + if(0 != flac_chmod(filename, stats.st_mode)) + return false; + } + else + return false; + + return true; +} + +FLAC__bool grabbag__file_are_same(const char *f1, const char *f2) +{ +#if defined _MSC_VER || defined __MINGW32__ + /* see + * http://www.hydrogenaudio.org/forums/index.php?showtopic=49439&pid=444300&st=0 + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileinformationbyhandle.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/by_handle_file_information_str.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp + * apparently both the files have to be open at the same time for the comparison to work + */ + FLAC__bool same = false; + BY_HANDLE_FILE_INFORMATION info1, info2; + HANDLE h1, h2; + BOOL ok = 1; + h1 = CreateFile_utf8(f1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + h2 = CreateFile_utf8(f2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE) + ok = 0; + ok &= GetFileInformationByHandle(h1, &info1); + ok &= GetFileInformationByHandle(h2, &info2); + if(ok) + same = + info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber && + info1.nFileIndexHigh == info2.nFileIndexHigh && + info1.nFileIndexLow == info2.nFileIndexLow + ; + if(h1 != INVALID_HANDLE_VALUE) + CloseHandle(h1); + if(h2 != INVALID_HANDLE_VALUE) + CloseHandle(h2); + return same; +#else + struct flac_stat_s s1, s2; + return f1 && f2 && flac_stat(f1, &s1) == 0 && flac_stat(f2, &s2) == 0 && s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev; +#endif +} + +FLAC__bool grabbag__file_remove_file(const char *filename) +{ + return grabbag__file_change_stats(filename, /*read_only=*/false) && 0 == flac_unlink(filename); +} + +FILE *grabbag__file_get_binary_stdin(void) +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdin), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdin), _O_BINARY); +#elif defined __EMX__ + setmode(fileno(stdin), O_BINARY); +#endif + + return stdin; +} + +FILE *grabbag__file_get_binary_stdout(void) +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdout), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdout), _O_BINARY); +#elif defined __EMX__ + setmode(fileno(stdout), O_BINARY); +#endif + + return stdout; +} diff --git a/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcproj b/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcproj new file mode 100644 index 0000000..bb70706 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcproj @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="grabbag_static"
+ ProjectGUID="{4cefbc81-c215-11db-8314-0800200c9a66}"
+ RootNamespace="grabbag_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\alloc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\cuesheet.c"
+ >
+ </File>
+ <File
+ RelativePath=".\file.c"
+ >
+ </File>
+ <File
+ RelativePath=".\picture.c"
+ >
+ </File>
+ <File
+ RelativePath=".\replaygain.c"
+ >
+ </File>
+ <File
+ RelativePath=".\seektable.c"
+ >
+ </File>
+ <File
+ RelativePath=".\snprintf.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\..\include\share\grabbag.h"
+ >
+ </File>
+ <Filter
+ Name="grabbag"
+ >
+ <File
+ RelativePath="..\..\..\include\share\grabbag\cuesheet.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\share\grabbag\file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\share\grabbag\picture.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\share\grabbag\replaygain.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\share\grabbag\seektable.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj b/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj new file mode 100644 index 0000000..8e7b6fd --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc81-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>grabbag_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="alloc.c" />
+ <ClCompile Include="cuesheet.c" />
+ <ClCompile Include="file.c" />
+ <ClCompile Include="picture.c" />
+ <ClCompile Include="replaygain.c" />
+ <ClCompile Include="seektable.c" />
+ <ClCompile Include="snprintf.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\grabbag.h" />
+ <ClInclude Include="..\..\..\include\share\grabbag\cuesheet.h" />
+ <ClInclude Include="..\..\..\include\share\grabbag\file.h" />
+ <ClInclude Include="..\..\..\include\share\grabbag\picture.h" />
+ <ClInclude Include="..\..\..\include\share\grabbag\replaygain.h" />
+ <ClInclude Include="..\..\..\include\share\grabbag\seektable.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\libFLAC\libFLAC_static.vcxproj">
+ <Project>{4cefbc84-c215-11db-8314-0800200c9a66}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ <ProjectReference Include="..\replaygain_analysis\replaygain_analysis_static.vcxproj">
+ <Project>{4cefbc89-c215-11db-8314-0800200c9a66}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj.filters b/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj.filters new file mode 100644 index 0000000..421b6d5 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/grabbag_static.vcxproj.filters @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{d4e83ff0-6406-4b76-bd64-6192e6b8e47a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Public Header Files\grabbag">
+ <UniqueIdentifier>{82df5da8-3a2c-402e-a7cd-a88de1a7be91}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="alloc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="cuesheet.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="file.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="picture.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="replaygain.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="seektable.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="snprintf.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\grabbag.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\include\share\grabbag\cuesheet.h">
+ <Filter>Public Header Files\grabbag</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\include\share\grabbag\file.h">
+ <Filter>Public Header Files\grabbag</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\include\share\grabbag\picture.h">
+ <Filter>Public Header Files\grabbag</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\include\share\grabbag\replaygain.h">
+ <Filter>Public Header Files\grabbag</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\include\share\grabbag\seektable.h">
+ <Filter>Public Header Files\grabbag</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/grabbag/picture.c b/deps/flac-1.3.2/src/share/grabbag/picture.c new file mode 100644 index 0000000..f63b5a9 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/picture.c @@ -0,0 +1,508 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2006-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * 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 + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "share/alloc.h" +#include "share/grabbag.h" +#include "FLAC/assert.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "share/compat.h" +#include "share/safe_str.h" + +/* slightly different that strndup(): this always copies 'size' bytes starting from s into a NUL-terminated string. */ +static char *local__strndup_(const char *s, size_t size) +{ + char *x = safe_malloc_add_2op_(size, /*+*/1); + if(x) { + memcpy(x, s, size); + x[size] = '\0'; + } + return x; +} + +static FLAC__bool local__parse_type_(const char *s, size_t len, FLAC__StreamMetadata_Picture *picture) +{ + size_t i; + FLAC__uint32 val = 0; + + picture->type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER; + + if(len == 0) + return true; /* empty string implies default to 'front cover' */ + + for(i = 0; i < len; i++) { + if(s[i] >= '0' && s[i] <= '9') + val = 10*val + (FLAC__uint32)(s[i] - '0'); + else + return false; + } + + if(i == len) + picture->type = val; + else + return false; + + return true; +} + +static FLAC__bool local__parse_resolution_(const char *s, size_t len, FLAC__StreamMetadata_Picture *picture) +{ + int state = 0; + size_t i; + FLAC__uint32 val = 0; + + picture->width = picture->height = picture->depth = picture->colors = 0; + + if(len == 0) + return true; /* empty string implies client wants to get info from the file itself */ + + for(i = 0; i < len; i++) { + if(s[i] == 'x') { + if(state == 0) + picture->width = val; + else if(state == 1) + picture->height = val; + else + return false; + state++; + val = 0; + } + else if(s[i] == '/') { + if(state == 2) + picture->depth = val; + else + return false; + state++; + val = 0; + } + else if(s[i] >= '0' && s[i] <= '9') + val = 10*val + (FLAC__uint32)(s[i] - '0'); + else + return false; + } + + if(state < 2) + return false; + else if(state == 2) + picture->depth = val; + else if(state == 3) + picture->colors = val; + else + return false; + if(picture->depth < 32 && 1u<<picture->depth < picture->colors) + return false; + + return true; +} + +static FLAC__bool local__extract_mime_type_(FLAC__StreamMetadata *obj) +{ + if(obj->data.picture.data_length >= 8 && 0 == memcmp(obj->data.picture.data, "\x89PNG\x0d\x0a\x1a\x0a", 8)) + return FLAC__metadata_object_picture_set_mime_type(obj, "image/png", /*copy=*/true); + else if(obj->data.picture.data_length >= 6 && (0 == memcmp(obj->data.picture.data, "GIF87a", 6) || 0 == memcmp(obj->data.picture.data, "GIF89a", 6))) + return FLAC__metadata_object_picture_set_mime_type(obj, "image/gif", /*copy=*/true); + else if(obj->data.picture.data_length >= 2 && 0 == memcmp(obj->data.picture.data, "\xff\xd8", 2)) + return FLAC__metadata_object_picture_set_mime_type(obj, "image/jpeg", /*copy=*/true); + return false; +} + +static FLAC__bool local__extract_resolution_color_info_(FLAC__StreamMetadata_Picture *picture) +{ + const FLAC__byte *data = picture->data; + FLAC__uint32 len = picture->data_length; + + if(0 == strcmp(picture->mime_type, "image/png")) { + /* c.f. http://www.w3.org/TR/PNG/ */ + FLAC__bool need_palette = false; /* if IHDR has color_type=3, we need to also read the PLTE chunk to get the #colors */ + if(len < 8 || memcmp(data, "\x89PNG\x0d\x0a\x1a\x0a", 8)) + return false; + /* try to find IHDR chunk */ + data += 8; + len -= 8; + while(len > 12) { /* every PNG chunk must be at least 12 bytes long */ + const FLAC__uint32 clen = (FLAC__uint32)data[0] << 24 | (FLAC__uint32)data[1] << 16 | (FLAC__uint32)data[2] << 8 | (FLAC__uint32)data[3]; + if(0 == memcmp(data+4, "IHDR", 4) && clen == 13) { + unsigned color_type = data[17]; + picture->width = (FLAC__uint32)data[8] << 24 | (FLAC__uint32)data[9] << 16 | (FLAC__uint32)data[10] << 8 | (FLAC__uint32)data[11]; + picture->height = (FLAC__uint32)data[12] << 24 | (FLAC__uint32)data[13] << 16 | (FLAC__uint32)data[14] << 8 | (FLAC__uint32)data[15]; + if(color_type == 3) { + /* even though the bit depth for color_type==3 can be 1,2,4,or 8, + * the spec in 11.2.2 of http://www.w3.org/TR/PNG/ says that the + * sample depth is always 8 + */ + picture->depth = 8 * 3u; + need_palette = true; + data += 12 + clen; + len -= 12 + clen; + } + else { + if(color_type == 0) /* greyscale, 1 sample per pixel */ + picture->depth = (FLAC__uint32)data[16]; + if(color_type == 2) /* truecolor, 3 samples per pixel */ + picture->depth = (FLAC__uint32)data[16] * 3u; + if(color_type == 4) /* greyscale+alpha, 2 samples per pixel */ + picture->depth = (FLAC__uint32)data[16] * 2u; + if(color_type == 6) /* truecolor+alpha, 4 samples per pixel */ + picture->depth = (FLAC__uint32)data[16] * 4u; + picture->colors = 0; + return true; + } + } + else if(need_palette && 0 == memcmp(data+4, "PLTE", 4)) { + picture->colors = clen / 3u; + return true; + } + else if(clen + 12 > len) + return false; + else { + data += 12 + clen; + len -= 12 + clen; + } + } + } + else if(0 == strcmp(picture->mime_type, "image/jpeg")) { + /* c.f. http://www.w3.org/Graphics/JPEG/itu-t81.pdf and Q22 of http://www.faqs.org/faqs/jpeg-faq/part1/ */ + if(len < 2 || memcmp(data, "\xff\xd8", 2)) + return false; + data += 2; + len -= 2; + while(1) { + /* look for sync FF byte */ + for( ; len > 0; data++, len--) { + if(*data == 0xff) + break; + } + if(len == 0) + return false; + /* eat any extra pad FF bytes before marker */ + for( ; len > 0; data++, len--) { + if(*data != 0xff) + break; + } + if(len == 0) + return false; + /* if we hit SOS or EOI, bail */ + if(*data == 0xda || *data == 0xd9) + return false; + /* looking for some SOFn */ + else if(memchr("\xc0\xc1\xc2\xc3\xc5\xc6\xc7\xc9\xca\xcb\xcd\xce\xcf", *data, 13)) { + data++; len--; /* skip marker byte */ + if(len < 2) + return false; + else { + const FLAC__uint32 clen = (FLAC__uint32)data[0] << 8 | (FLAC__uint32)data[1]; + if(clen < 8 || len < clen) + return false; + picture->width = (FLAC__uint32)data[5] << 8 | (FLAC__uint32)data[6]; + picture->height = (FLAC__uint32)data[3] << 8 | (FLAC__uint32)data[4]; + picture->depth = (FLAC__uint32)data[2] * (FLAC__uint32)data[7]; + picture->colors = 0; + return true; + } + } + /* else skip it */ + else { + data++; len--; /* skip marker byte */ + if(len < 2) + return false; + else { + const FLAC__uint32 clen = (FLAC__uint32)data[0] << 8 | (FLAC__uint32)data[1]; + if(clen < 2 || len < clen) + return false; + data += clen; + len -= clen; + } + } + } + } + else if(0 == strcmp(picture->mime_type, "image/gif")) { + /* c.f. http://www.w3.org/Graphics/GIF/spec-gif89a.txt */ + if(len < 14) + return false; + if(memcmp(data, "GIF87a", 6) && memcmp(data, "GIF89a", 6)) + return false; +#if 0 + /* according to the GIF spec, even if the GCTF is 0, the low 3 bits should still tell the total # colors used */ + if(data[10] & 0x80 == 0) + return false; +#endif + picture->width = (FLAC__uint32)data[6] | ((FLAC__uint32)data[7] << 8); + picture->height = (FLAC__uint32)data[8] | ((FLAC__uint32)data[9] << 8); +#if 0 + /* this value doesn't seem to be reliable... */ + picture->depth = (((FLAC__uint32)(data[10] & 0x70) >> 4) + 1) * 3u; +#else + /* ...just pessimistically assume it's 24-bit color without scanning all the color tables */ + picture->depth = 8u * 3u; +#endif + picture->colors = 1u << ((FLAC__uint32)(data[10] & 0x07) + 1u); + return true; + } + return false; +} + +static const char *error_messages[] = { + "memory allocation error", + "invalid picture specification", + "invalid picture specification: can't parse resolution/color part", + "unable to extract resolution and color info from URL, user must set explicitly", + "unable to extract resolution and color info from file, user must set explicitly", + "error opening picture file", + "error reading picture file", + "invalid picture type", + "unable to guess MIME type from file, user must set explicitly", + "type 1 icon must be a 32x32 pixel PNG", + "file not found", /* currently unused */ + "file is too large" +}; + +static const char * read_file (const char * filepath, FLAC__StreamMetadata * obj) +{ + const FLAC__off_t size = grabbag__file_get_filesize(filepath); + FLAC__byte *buffer; + FILE *file; + const char *error_message=NULL; + + if (size < 0) + return error_messages[5]; + + if (size >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) /* actual limit is less because of other fields in the PICTURE metadata block */ + return error_messages[11]; + + if ((buffer = safe_malloc_(size)) == NULL) + return error_messages[0]; + + if ((file = flac_fopen(filepath, "rb")) == NULL) { + free(buffer); + return error_messages[5]; + } + + if (fread(buffer, 1, size, file) != (size_t) size) { + fclose(file); + free(buffer); + return error_messages[6]; + } + fclose(file); + + if (!FLAC__metadata_object_picture_set_data(obj, buffer, size, /*copy=*/false)) + error_message = error_messages[6]; + /* try to extract MIME type if user left it blank */ + else if (*obj->data.picture.mime_type == '\0' && !local__extract_mime_type_(obj)) + error_message = error_messages[8]; + /* try to extract resolution/color info if user left it blank */ + else if ((obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0) && !local__extract_resolution_color_info_(&obj->data.picture)) + error_message = error_messages[4]; + /* check metadata block size */ + else if (obj->length >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + error_message = error_messages[11]; + + return error_message; +} + +FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, const char **error_message) +{ + FLAC__StreamMetadata *obj; + int state = 0; + + FLAC__ASSERT(0 != spec); + FLAC__ASSERT(0 != error_message); + + /* double protection */ + if(0 == spec) + return 0; + if(0 == error_message) + return 0; + + *error_message = 0; + + if(0 == (obj = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE))) { + *error_message = error_messages[0]; + return obj; + } + + if(strchr(spec, '|')) { /* full format */ + const char *p; + char *q; + for(p = spec; *error_message==0 && *p; ) { + if(*p == '|') { + switch(state) { + case 0: /* type */ + if(!local__parse_type_(spec, p-spec, &obj->data.picture)) + *error_message = error_messages[7]; + break; + case 1: /* mime type */ + if(p-spec) { /* if blank, we'll try to guess later from the picture data */ + if(0 == (q = local__strndup_(spec, p-spec))) + *error_message = error_messages[0]; + else if(!FLAC__metadata_object_picture_set_mime_type(obj, q, /*copy=*/false)) + *error_message = error_messages[0]; + } + break; + case 2: /* description */ + if(0 == (q = local__strndup_(spec, p-spec))) + *error_message = error_messages[0]; + else if(!FLAC__metadata_object_picture_set_description(obj, (FLAC__byte*)q, /*copy=*/false)) + *error_message = error_messages[0]; + break; + case 3: /* resolution/color (e.g. [300x300x16[/1234]] */ + if(!local__parse_resolution_(spec, p-spec, &obj->data.picture)) + *error_message = error_messages[2]; + break; + default: + *error_message = error_messages[1]; + break; + } + p++; + spec = p; + state++; + } + else + p++; + } + } + else { /* simple format, filename only, everything else guessed */ + if(!local__parse_type_("", 0, &obj->data.picture)) /* use default picture type */ + *error_message = error_messages[7]; + /* leave MIME type to be filled in later */ + /* leave description empty */ + /* leave the rest to be filled in later: */ + else if(!local__parse_resolution_("", 0, &obj->data.picture)) + *error_message = error_messages[2]; + else + state = 4; + } + + /* parse filename, read file, try to extract resolution/color info if needed */ + if(*error_message == 0) { + if(state != 4) + *error_message = error_messages[1]; + else { /* 'spec' points to filename/URL */ + if(0 == strcmp(obj->data.picture.mime_type, "-->")) { /* magic MIME type means URL */ + if(!FLAC__metadata_object_picture_set_data(obj, (FLAC__byte*)spec, strlen(spec), /*copy=*/true)) + *error_message = error_messages[0]; + else if(obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0) + *error_message = error_messages[3]; + } + else { /* regular picture file */ + *error_message = read_file (spec, obj); + } + } + } + + if(*error_message == 0) { + if( + obj->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD && + ( + (strcmp(obj->data.picture.mime_type, "image/png") && strcmp(obj->data.picture.mime_type, "-->")) || + obj->data.picture.width != 32 || + obj->data.picture.height != 32 + ) + ) + *error_message = error_messages[9]; + } + + if(*error_message && obj) { + FLAC__metadata_object_delete(obj); + obj = 0; + } + + return obj; +} + +FLAC__StreamMetadata *grabbag__picture_from_specification(int type, const char *mime_type_in, const char * description, + const PictureResolution * res, const char * filepath, const char **error_message) +{ + + FLAC__StreamMetadata *obj; + char mime_type [64] ; + + if (error_message == 0) + return 0; + + safe_strncpy(mime_type, mime_type_in, sizeof (mime_type)); + + *error_message = 0; + + if ((obj = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE)) == 0) { + *error_message = error_messages[0]; + return obj; + } + + /* Picture type if known. */ + obj->data.picture.type = type >= 0 ? type : FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER; + + /* Mime type if known. */ + if (mime_type_in && ! FLAC__metadata_object_picture_set_mime_type(obj, mime_type, /*copy=*/true)) { + *error_message = error_messages[0]; + return obj; + } + + /* Description if present. */ + if (description && ! FLAC__metadata_object_picture_set_description(obj, (FLAC__byte*) description, /*copy=*/true)) { + *error_message = error_messages[0]; + return obj; + } + + if (res == NULL) { + obj->data.picture.width = 0; + obj->data.picture.height = 0; + obj->data.picture.depth = 0; + obj->data.picture.colors = 0; + } + else { + obj->data.picture.width = res->width; + obj->data.picture.height = res->height; + obj->data.picture.depth = res->depth; + obj->data.picture.colors = res->colors; + } + + if (strcmp(obj->data.picture.mime_type, "-->") == 0) { /* magic MIME type means URL */ + if (!FLAC__metadata_object_picture_set_data(obj, (FLAC__byte*)filepath, strlen(filepath), /*copy=*/true)) + *error_message = error_messages[0]; + else if (obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0) + *error_message = error_messages[3]; + } + else { + *error_message = read_file (filepath, obj); + } + + if (*error_message == NULL) { + if ( + obj->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD && + ( + (strcmp(obj->data.picture.mime_type, "image/png") && strcmp(obj->data.picture.mime_type, "-->")) || + obj->data.picture.width != 32 || + obj->data.picture.height != 32 + ) + ) + *error_message = error_messages[9]; + } + + if (*error_message && obj) { + FLAC__metadata_object_delete(obj); + obj = 0; + } + + return obj; +} diff --git a/deps/flac-1.3.2/src/share/grabbag/replaygain.c b/deps/flac-1.3.2/src/share/grabbag/replaygain.c new file mode 100644 index 0000000..ad3138f --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/replaygain.c @@ -0,0 +1,668 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <locale.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined _MSC_VER || defined __MINGW32__ +#include <io.h> /* for chmod() */ +#endif +#include <sys/stat.h> /* for stat(), maybe chmod() */ + +#include "FLAC/assert.h" +#include "FLAC/metadata.h" +#include "FLAC/stream_decoder.h" +#include "share/grabbag.h" +#include "share/replaygain_analysis.h" +#include "share/safe_str.h" + +#ifdef local_min +#undef local_min +#endif +#define local_min(a,b) ((a)<(b)?(a):(b)) + +#ifdef local_max +#undef local_max +#endif +#define local_max(a,b) ((a)>(b)?(a):(b)) + +static const char *reference_format_ = "%s=%2.1f dB"; +static const char *gain_format_ = "%s=%+2.2f dB"; +static const char *peak_format_ = "%s=%1.8f"; + +static double album_peak_, title_peak_; + +const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED = 190; +/* + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 29 + 1 + 8 + + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 + + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12 + + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 + + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12 +*/ + +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS = (const FLAC__byte * const)"REPLAYGAIN_REFERENCE_LOUDNESS"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN = (const FLAC__byte * const)"REPLAYGAIN_TRACK_GAIN"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK = (const FLAC__byte * const)"REPLAYGAIN_TRACK_PEAK"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_GAIN"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_PEAK"; + + +static FLAC__bool get_file_stats_(const char *filename, struct flac_stat_s *stats) +{ + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != stats); + return (0 == flac_stat(filename, stats)); +} + +static void set_file_stats_(const char *filename, struct flac_stat_s *stats) +{ + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != stats); + + (void)flac_chmod(filename, stats->st_mode); +} + +static FLAC__bool append_tag_(FLAC__StreamMetadata *block, const char *format, const FLAC__byte *name, float value) +{ + char buffer[256]; + char *saved_locale; + FLAC__StreamMetadata_VorbisComment_Entry entry; + + FLAC__ASSERT(0 != block); + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + FLAC__ASSERT(0 != format); + FLAC__ASSERT(0 != name); + + buffer[sizeof(buffer)-1] = '\0'; + /* + * We need to save the old locale and switch to "C" because the locale + * influences the formatting of %f and we want it a certain way. + */ + saved_locale = strdup(setlocale(LC_ALL, 0)); + if (0 == saved_locale) + return false; + setlocale(LC_ALL, "C"); + flac_snprintf(buffer, sizeof(buffer), format, name, value); + setlocale(LC_ALL, saved_locale); + free(saved_locale); + + entry.entry = (FLAC__byte *)buffer; + entry.length = strlen(buffer); + + return FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true); +} + +FLAC__bool grabbag__replaygain_is_valid_sample_frequency(unsigned sample_frequency) +{ + return ValidGainFrequency( sample_frequency ); +} + +FLAC__bool grabbag__replaygain_init(unsigned sample_frequency) +{ + title_peak_ = album_peak_ = 0.0; + return InitGainAnalysis((long)sample_frequency) == INIT_GAIN_ANALYSIS_OK; +} + +FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__bool is_stereo, unsigned bps, unsigned samples) +{ + /* using a small buffer improves data locality; we'd like it to fit easily in the dcache */ + static flac_float_t lbuffer[2048], rbuffer[2048]; + static const unsigned nbuffer = sizeof(lbuffer) / sizeof(lbuffer[0]); + FLAC__int32 block_peak = 0, s; + unsigned i, j; + + FLAC__ASSERT(bps >= 4 && bps <= FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE); + FLAC__ASSERT(FLAC__MIN_BITS_PER_SAMPLE == 4); + /* + * We use abs() on a FLAC__int32 which is undefined for the most negative value. + * If the reference codec ever handles 32bps we will have to write a special + * case here. + */ + FLAC__ASSERT(FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE < 32); + + if(bps == 16) { + if(is_stereo) { + j = 0; + while(samples > 0) { + const unsigned n = local_min(samples, nbuffer); + for(i = 0; i < n; i++, j++) { + s = input[0][j]; + lbuffer[i] = (flac_float_t)s; + s = abs(s); + block_peak = local_max(block_peak, s); + + s = input[1][j]; + rbuffer[i] = (flac_float_t)s; + s = abs(s); + block_peak = local_max(block_peak, s); + } + samples -= n; + if(AnalyzeSamples(lbuffer, rbuffer, n, 2) != GAIN_ANALYSIS_OK) + return false; + } + } + else { + j = 0; + while(samples > 0) { + const unsigned n = local_min(samples, nbuffer); + for(i = 0; i < n; i++, j++) { + s = input[0][j]; + lbuffer[i] = (flac_float_t)s; + s = abs(s); + block_peak = local_max(block_peak, s); + } + samples -= n; + if(AnalyzeSamples(lbuffer, 0, n, 1) != GAIN_ANALYSIS_OK) + return false; + } + } + } + else { /* bps must be < 32 according to above assertion */ + const double scale = ( + (bps > 16)? + (double)1. / (double)(1u << (bps - 16)) : + (double)(1u << (16 - bps)) + ); + + if(is_stereo) { + j = 0; + while(samples > 0) { + const unsigned n = local_min(samples, nbuffer); + for(i = 0; i < n; i++, j++) { + s = input[0][j]; + lbuffer[i] = (flac_float_t)(scale * (double)s); + s = abs(s); + block_peak = local_max(block_peak, s); + + s = input[1][j]; + rbuffer[i] = (flac_float_t)(scale * (double)s); + s = abs(s); + block_peak = local_max(block_peak, s); + } + samples -= n; + if(AnalyzeSamples(lbuffer, rbuffer, n, 2) != GAIN_ANALYSIS_OK) + return false; + } + } + else { + j = 0; + while(samples > 0) { + const unsigned n = local_min(samples, nbuffer); + for(i = 0; i < n; i++, j++) { + s = input[0][j]; + lbuffer[i] = (flac_float_t)(scale * (double)s); + s = abs(s); + block_peak = local_max(block_peak, s); + } + samples -= n; + if(AnalyzeSamples(lbuffer, 0, n, 1) != GAIN_ANALYSIS_OK) + return false; + } + } + } + + { + const double peak_scale = (double)(1u << (bps - 1)); + double peak = (double)block_peak / peak_scale; + if(peak > title_peak_) + title_peak_ = peak; + if(peak > album_peak_) + album_peak_ = peak; + } + + return true; +} + +void grabbag__replaygain_get_album(float *gain, float *peak) +{ + *gain = (float)GetAlbumGain(); + *peak = (float)album_peak_; + album_peak_ = 0.0; +} + +void grabbag__replaygain_get_title(float *gain, float *peak) +{ + *gain = (float)GetTitleGain(); + *peak = (float)title_peak_; + title_peak_ = 0.0; +} + + +typedef struct { + unsigned channels; + unsigned bits_per_sample; + unsigned sample_rate; + FLAC__bool error; +} DecoderInstance; + +static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) +{ + DecoderInstance *instance = (DecoderInstance*)client_data; + const unsigned bits_per_sample = frame->header.bits_per_sample; + const unsigned channels = frame->header.channels; + const unsigned sample_rate = frame->header.sample_rate; + const unsigned samples = frame->header.blocksize; + + (void)decoder; + + if( + !instance->error && + (channels == 2 || channels == 1) && + bits_per_sample == instance->bits_per_sample && + channels == instance->channels && + sample_rate == instance->sample_rate + ) { + instance->error = !grabbag__replaygain_analyze(buffer, channels==2, bits_per_sample, samples); + } + else { + instance->error = true; + } + + if(!instance->error) + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; + else + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; +} + +static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + DecoderInstance *instance = (DecoderInstance*)client_data; + + (void)decoder; + + if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { + instance->bits_per_sample = metadata->data.stream_info.bits_per_sample; + instance->channels = metadata->data.stream_info.channels; + instance->sample_rate = metadata->data.stream_info.sample_rate; + + if(instance->channels != 1 && instance->channels != 2) { + instance->error = true; + return; + } + + if(!grabbag__replaygain_is_valid_sample_frequency(instance->sample_rate)) { + instance->error = true; + return; + } + } +} + +static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + DecoderInstance *instance = (DecoderInstance*)client_data; + + (void)decoder, (void)status; + + instance->error = true; +} + +const char *grabbag__replaygain_analyze_file(const char *filename, float *title_gain, float *title_peak) +{ + DecoderInstance instance; + FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); + + if(0 == decoder) + return "memory allocation error"; + + instance.error = false; + + /* It does these three by default but lets be explicit: */ + FLAC__stream_decoder_set_md5_checking(decoder, false); + FLAC__stream_decoder_set_metadata_ignore_all(decoder); + FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); + + if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &instance) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { + FLAC__stream_decoder_delete(decoder); + return "initializing decoder"; + } + + if(!FLAC__stream_decoder_process_until_end_of_stream(decoder) || instance.error) { + FLAC__stream_decoder_delete(decoder); + return "decoding file"; + } + + FLAC__stream_decoder_delete(decoder); + + grabbag__replaygain_get_title(title_gain, title_peak); + + return 0; +} + +const char *grabbag__replaygain_store_to_vorbiscomment(FLAC__StreamMetadata *block, float album_gain, float album_peak, float title_gain, float title_peak) +{ + const char *error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_album(block, album_gain, album_peak))) + return error; + + return 0; +} + +const char *grabbag__replaygain_store_to_vorbiscomment_reference(FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != block); + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + if(FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS) < 0) + return "memory allocation error"; + + if(!append_tag_(block, reference_format_, GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS, ReplayGainReferenceLoudness)) + return "memory allocation error"; + + return 0; +} + +const char *grabbag__replaygain_store_to_vorbiscomment_album(FLAC__StreamMetadata *block, float album_gain, float album_peak) +{ + FLAC__ASSERT(0 != block); + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + if( + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN) < 0 || + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK) < 0 + ) + return "memory allocation error"; + + if( + !append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN, album_gain) || + !append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK, album_peak) + ) + return "memory allocation error"; + + return 0; +} + +const char *grabbag__replaygain_store_to_vorbiscomment_title(FLAC__StreamMetadata *block, float title_gain, float title_peak) +{ + FLAC__ASSERT(0 != block); + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + if( + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN) < 0 || + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK) < 0 + ) + return "memory allocation error"; + + if( + !append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN, title_gain) || + !append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK, title_peak) + ) + return "memory allocation error"; + + return 0; +} + +static const char *store_to_file_pre_(const char *filename, FLAC__Metadata_Chain **chain, FLAC__StreamMetadata **block) +{ + FLAC__Metadata_Iterator *iterator; + const char *error; + FLAC__bool found_vc_block = false; + + if(0 == (*chain = FLAC__metadata_chain_new())) + return "memory allocation error"; + + if(!FLAC__metadata_chain_read(*chain, filename)) { + error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(*chain)]; + FLAC__metadata_chain_delete(*chain); + return error; + } + + if(0 == (iterator = FLAC__metadata_iterator_new())) { + FLAC__metadata_chain_delete(*chain); + return "memory allocation error"; + } + + FLAC__metadata_iterator_init(iterator, *chain); + + do { + *block = FLAC__metadata_iterator_get_block(iterator); + if((*block)->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) + found_vc_block = true; + } while(!found_vc_block && FLAC__metadata_iterator_next(iterator)); + + if(!found_vc_block) { + /* create a new block */ + *block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); + if(0 == *block) { + FLAC__metadata_chain_delete(*chain); + FLAC__metadata_iterator_delete(iterator); + return "memory allocation error"; + } + while(FLAC__metadata_iterator_next(iterator)) + ; + if(!FLAC__metadata_iterator_insert_block_after(iterator, *block)) { + error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(*chain)]; + FLAC__metadata_chain_delete(*chain); + FLAC__metadata_iterator_delete(iterator); + return error; + } + /* iterator is left pointing to new block */ + FLAC__ASSERT(FLAC__metadata_iterator_get_block(iterator) == *block); + } + + FLAC__metadata_iterator_delete(iterator); + + FLAC__ASSERT(0 != *block); + FLAC__ASSERT((*block)->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + return 0; +} + +static const char *store_to_file_post_(const char *filename, FLAC__Metadata_Chain *chain, FLAC__bool preserve_modtime) +{ + struct flac_stat_s stats; + const FLAC__bool have_stats = get_file_stats_(filename, &stats); + + (void)grabbag__file_change_stats(filename, /*read_only=*/false); + + FLAC__metadata_chain_sort_padding(chain); + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, preserve_modtime)) { + const char *error; + error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(chain)]; + FLAC__metadata_chain_delete(chain); + return error; + } + + FLAC__metadata_chain_delete(chain); + + if(have_stats) + set_file_stats_(filename, &stats); + + return 0; +} + +const char *grabbag__replaygain_store_to_file(const char *filename, float album_gain, float album_peak, float title_gain, float title_peak, FLAC__bool preserve_modtime) +{ + FLAC__Metadata_Chain *chain; + FLAC__StreamMetadata *block = NULL; + const char *error; + + if(0 != (error = store_to_file_pre_(filename, &chain, &block))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment(block, album_gain, album_peak, title_gain, title_peak))) { + FLAC__metadata_chain_delete(chain); + return error; + } + + if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime))) + return error; + + return 0; +} + +const char *grabbag__replaygain_store_to_file_reference(const char *filename, FLAC__bool preserve_modtime) +{ + FLAC__Metadata_Chain *chain; + FLAC__StreamMetadata *block = NULL; + const char *error; + + if(0 != (error = store_to_file_pre_(filename, &chain, &block))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block))) { + FLAC__metadata_chain_delete(chain); + return error; + } + + if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime))) + return error; + + return 0; +} + +const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime) +{ + FLAC__Metadata_Chain *chain; + FLAC__StreamMetadata *block = NULL; + const char *error; + + if(0 != (error = store_to_file_pre_(filename, &chain, &block))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_album(block, album_gain, album_peak))) { + FLAC__metadata_chain_delete(chain); + return error; + } + + if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime))) + return error; + + return 0; +} + +const char *grabbag__replaygain_store_to_file_title(const char *filename, float title_gain, float title_peak, FLAC__bool preserve_modtime) +{ + FLAC__Metadata_Chain *chain; + FLAC__StreamMetadata *block = NULL; + const char *error; + + if(0 != (error = store_to_file_pre_(filename, &chain, &block))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak))) { + FLAC__metadata_chain_delete(chain); + return error; + } + + if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime))) + return error; + + return 0; +} + +static FLAC__bool parse_double_(const FLAC__StreamMetadata_VorbisComment_Entry *entry, double *val) +{ + char s[32], *end; + const char *p, *q; + double v; + + FLAC__ASSERT(0 != entry); + FLAC__ASSERT(0 != val); + + p = (const char *)entry->entry; + q = strchr(p, '='); + if(0 == q) + return false; + q++; + safe_strncpy(s, q, local_min(sizeof(s), (size_t) (entry->length - (q-p)))); + + v = strtod(s, &end); + if(end == s) + return false; + + *val = v; + return true; +} + +FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak) +{ + int reference_offset, gain_offset, peak_offset; + char *saved_locale; + FLAC__bool res = true; + + FLAC__ASSERT(0 != block); + FLAC__ASSERT(0 != reference); + FLAC__ASSERT(0 != gain); + FLAC__ASSERT(0 != peak); + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + /* Default to current level until overridden by a detected tag; this + * will always be true until we change replaygain_analysis.c + */ + *reference = ReplayGainReferenceLoudness; + + /* + * We need to save the old locale and switch to "C" because the locale + * influences the behaviour of strtod and we want it a certain way. + */ + saved_locale = strdup(setlocale(LC_ALL, 0)); + if (0 == saved_locale) + return false; + setlocale(LC_ALL, "C"); + + if(0 <= (reference_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS))) + (void)parse_double_(block->data.vorbis_comment.comments + reference_offset, reference); + + if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN : GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN)))) + res = false; + if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK : GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK)))) + res = false; + + if(res && !parse_double_(block->data.vorbis_comment.comments + gain_offset, gain)) + res = false; + if(res && !parse_double_(block->data.vorbis_comment.comments + peak_offset, peak)) + res = false; + + setlocale(LC_ALL, saved_locale); + free(saved_locale); + + /* something failed; retry with strict */ + if (!res && !strict) + res = grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); + + return res; +} + +double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping) +{ + double scale; + FLAC__ASSERT(peak >= 0.0); + gain += preamp; + scale = (float) pow(10.0, gain * 0.05); + if(prevent_clipping && peak > 0.0) { + const double max_scale = (float)(1.0 / peak); + if(scale > max_scale) + scale = max_scale; + } + return scale; +} diff --git a/deps/flac-1.3.2/src/share/grabbag/seektable.c b/deps/flac-1.3.2/src/share/grabbag/seektable.c new file mode 100644 index 0000000..01118d5 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/seektable.c @@ -0,0 +1,106 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "share/grabbag.h" +#include "share/compat.h" +#include "FLAC/assert.h" +#include <stdlib.h> /* for atoi() */ +#include <string.h> + +FLAC__bool grabbag__seektable_convert_specification_to_template(const char *spec, FLAC__bool only_explicit_placeholders, FLAC__uint64 total_samples_to_encode, unsigned sample_rate, FLAC__StreamMetadata *seektable_template, FLAC__bool *spec_has_real_points) +{ + unsigned i; + const char *pt; + + FLAC__ASSERT(0 != spec); + FLAC__ASSERT(0 != seektable_template); + FLAC__ASSERT(seektable_template->type == FLAC__METADATA_TYPE_SEEKTABLE); + + if(0 != spec_has_real_points) + *spec_has_real_points = false; + + for(pt = spec, i = 0; pt && *pt; i++) { + const char *q = strchr(pt, ';'); + FLAC__ASSERT(0 != q); + + if(q > pt) { + if(0 == strncmp(pt, "X;", 2)) { /* -S X */ + if(!FLAC__metadata_object_seektable_template_append_placeholders(seektable_template, 1)) + return false; + } + else if(q[-1] == 'x') { /* -S #x */ + if(total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */ + if(0 != spec_has_real_points) + *spec_has_real_points = true; + if(!only_explicit_placeholders) { + const int n = (unsigned)atoi(pt); + if(n > 0) + if(!FLAC__metadata_object_seektable_template_append_spaced_points(seektable_template, (unsigned)n, total_samples_to_encode)) + return false; + } + } + } + else if(q[-1] == 's') { /* -S #s */ + if(total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */ + FLAC__ASSERT(sample_rate > 0); + if(0 != spec_has_real_points) + *spec_has_real_points = true; + if(!only_explicit_placeholders) { + const double sec = atof(pt); + if(sec > 0.0) { + unsigned samples = (unsigned)(sec * (double)sample_rate); + /* Restrict seekpoints to two per second of audio. */ + samples = samples < sample_rate / 2 ? sample_rate / 2 : samples; + if(samples > 0) { + /* +1 for the initial point at sample 0 */ + if(!FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(seektable_template, samples, total_samples_to_encode)) + return false; + } + } + } + } + } + else { /* -S # */ + if(0 != spec_has_real_points) + *spec_has_real_points = true; + if(!only_explicit_placeholders) { + char *endptr; + const FLAC__int64 n = (FLAC__int64)strtoll(pt, &endptr, 10); + if( + (n > 0 || (endptr > pt && *endptr == ';')) && /* is a valid number (extra check needed for "0") */ + (total_samples_to_encode == 0 || (FLAC__uint64)n < total_samples_to_encode) /* number is not >= the known total_samples_to_encode */ + ) + if(!FLAC__metadata_object_seektable_template_append_point(seektable_template, (FLAC__uint64)n)) + return false; + } + } + } + + pt = ++q; + } + + if(!FLAC__metadata_object_seektable_template_sort(seektable_template, /*compact=*/true)) + return false; + + return true; +} diff --git a/deps/flac-1.3.2/src/share/grabbag/snprintf.c b/deps/flac-1.3.2/src/share/grabbag/snprintf.c new file mode 100644 index 0000000..d8e4be3 --- /dev/null +++ b/deps/flac-1.3.2/src/share/grabbag/snprintf.c @@ -0,0 +1,101 @@ +/* grabbag - Convenience lib for various routines common to several tools + * Copyright (C) 2013-2016 Xiph.org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdarg.h> + +#include "share/compat.h" + +/* + * FLAC needs to compile and work correctly on systems with a normal ISO C99 + * snprintf as well as Microsoft Visual Studio which has an non-standards + * conformant snprint_s function. + * + * The important difference occurs when the resultant string (plus string + * terminator) would have been longer than the supplied size parameter. When + * this happens, ISO C's snprintf returns the length of resultant string, but + * does not over-write the end of the buffer. MS's snprintf_s in this case + * returns -1. + * + * The _MSC_VER code below attempts to modify the return code for vsnprintf_s + * to something that is more compatible with the behaviour of the ISO C version. + */ + +int +flac_snprintf(char *str, size_t size, const char *fmt, ...) +{ + va_list va; + int rc; + +#if defined _MSC_VER + if (size == 0) + return 1024; +#endif + + va_start (va, fmt); + +#if defined _MSC_VER + rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va); + if (rc < 0) + rc = size - 1; +#elif defined __MINGW32__ + rc = __mingw_vsnprintf (str, size, fmt, va); +#else + rc = vsnprintf (str, size, fmt, va); +#endif + va_end (va); + + return rc; +} + +int +flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va) +{ + int rc; + +#if defined _MSC_VER + if (size == 0) + return 1024; + rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va); + if (rc < 0) + rc = size - 1; +#elif defined __MINGW32__ + rc = __mingw_vsnprintf (str, size, fmt, va); +#else + rc = vsnprintf (str, size, fmt, va); +#endif + + return rc; +} diff --git a/deps/flac-1.3.2/src/share/replaygain_analysis/Makefile.lite b/deps/flac-1.3.2/src/share/replaygain_analysis/Makefile.lite new file mode 100644 index 0000000..4fa2cc9 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_analysis/Makefile.lite @@ -0,0 +1,15 @@ +# +# GNU makefile +# + +topdir = ../../.. + +LIB_NAME = libreplaygain_analysis +INCLUDES = -I$(topdir)/include + +SRCS_C = \ + replaygain_analysis.c + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis.c b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis.c new file mode 100644 index 0000000..20a5b28 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis.c @@ -0,0 +1,572 @@ +/* + * ReplayGainAnalysis - analyzes input samples and give the recommended dB change + * Copyright (C) 2001 David Robinson and Glen Sawyer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * concept and filter values by David Robinson (David@Robinson.org) + * -- blame him if you think the idea is flawed + * original coding by Glen Sawyer (glensawyer@hotmail.com) + * -- blame him if you think this runs too slowly, or the coding is otherwise flawed + * + * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) + * -- credit him for all the _good_ programming ;) + * + * minor cosmetic tweaks to integrate with FLAC by Josh Coalson + * + * + * For an explanation of the concepts and the basic algorithms involved, go to: + * http://www.replaygain.org/ + */ + +/* + * Here's the deal. Call + * + * InitGainAnalysis ( long samplefreq ); + * + * to initialize everything. Call + * + * AnalyzeSamples ( const flac_float_t* left_samples, + * const flac_float_t* right_samples, + * size_t num_samples, + * int num_channels ); + * + * as many times as you want, with as many or as few samples as you want. + * If mono, pass the sample buffer in through left_samples, leave + * right_samples NULL, and make sure num_channels = 1. + * + * GetTitleGain() + * + * will return the recommended dB level change for all samples analyzed + * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). + * + * GetAlbumGain() + * + * will return the recommended dB level change for all samples analyzed + * since InitGainAnalysis() was called and finalized with GetTitleGain(). + * + * Pseudo-code to process an album: + * + * flac_float_t l_samples [4096]; + * flac_float_t r_samples [4096]; + * size_t num_samples; + * unsigned int num_songs; + * unsigned int i; + * + * InitGainAnalysis ( 44100 ); + * for ( i = 1; i <= num_songs; i++ ) { + * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) + * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); + * fprintf ("Recommended dB change for song %2d: %+6.2f dB\n", i, GetTitleGain() ); + * } + * fprintf ("Recommended dB change for whole album: %+6.2f dB\n", GetAlbumGain() ); + */ + +/* + * So here's the main source of potential code confusion: + * + * The filters applied to the incoming samples are IIR filters, + * meaning they rely on up to <filter order> number of previous samples + * AND up to <filter order> number of previous filtered samples. + * + * I set up the AnalyzeSamples routine to minimize memory usage and interface + * complexity. The speed isn't compromised too much (I don't think), but the + * internal complexity is higher than it should be for such a relatively + * simple routine. + * + * Optimization/clarity suggestions are welcome. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "share/alloc.h" +#include "share/compat.h" +#include "share/replaygain_analysis.h" + +flac_float_t ReplayGainReferenceLoudness = 89.0; /* in dB SPL */ + +#define YULE_ORDER 10 +#define BUTTER_ORDER 2 +#define RMS_PERCENTILE 0.95 /* percentile which is louder than the proposed level */ +#define RMS_WINDOW_TIME 50 /* Time slice size [ms] */ +#define STEPS_per_dB 100. /* Table entries per dB */ +#define MAX_dB 120. /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */ + +#define MAX_ORDER (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER) +#define PINK_REF 64.82 /* 298640883795 */ /* calibration value */ + +static flac_float_t linprebuf [MAX_ORDER * 2]; +static flac_float_t* linpre; /* left input samples, with pre-buffer */ +static flac_float_t* lstepbuf; +static flac_float_t* lstep; /* left "first step" (i.e. post first filter) samples */ +static flac_float_t* loutbuf; +static flac_float_t* lout; /* left "out" (i.e. post second filter) samples */ +static flac_float_t rinprebuf [MAX_ORDER * 2]; +static flac_float_t* rinpre; /* right input samples ... */ +static flac_float_t* rstepbuf; +static flac_float_t* rstep; +static flac_float_t* routbuf; +static flac_float_t* rout; +static unsigned int sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */ +static unsigned long totsamp; +static double lsum; +static double rsum; +#if 0 +static uint32_t A [(size_t)(STEPS_per_dB * MAX_dB)]; +static uint32_t B [(size_t)(STEPS_per_dB * MAX_dB)]; +#else +/* [JEC] Solaris Forte compiler doesn't like float calc in array indices */ +static uint32_t A [120 * 100]; +static uint32_t B [120 * 100]; +#endif + +#ifdef _MSC_VER +#pragma warning ( disable : 4305 ) +#endif + +struct ReplayGainFilter { + long rate; + unsigned downsample; + flac_float_t BYule[YULE_ORDER+1]; + flac_float_t AYule[YULE_ORDER+1]; + flac_float_t BButter[BUTTER_ORDER+1]; + flac_float_t AButter[BUTTER_ORDER+1]; +}; + +static struct ReplayGainFilter *replaygainfilter; + +static const struct ReplayGainFilter ReplayGainFilters[] = { + + { + 48000, 0, /* ORIGINAL */ + { 0.03857599435200, -0.02160367184185, -0.00123395316851, -0.00009291677959, -0.01655260341619, 0.02161526843274, -0.02074045215285, 0.00594298065125, 0.00306428023191, 0.00012025322027, 0.00288463683916 }, + { 1.00000000000000, -3.84664617118067, 7.81501653005538, -11.34170355132042, 13.05504219327545, -12.28759895145294, 9.48293806319790, -5.87257861775999, 2.75465861874613, -0.86984376593551, 0.13919314567432 }, + { 0.98621192462708, -1.97242384925416, 0.98621192462708 }, + { 1.00000000000000, -1.97223372919527, 0.97261396931306 }, + }, + + { + 44100, 0, /* ORIGINAL */ + { 0.05418656406430, -0.02911007808948, -0.00848709379851, -0.00851165645469, -0.00834990904936, 0.02245293253339, -0.02596338512915, 0.01624864962975, -0.00240879051584, 0.00674613682247, -0.00187763777362 }, + { 1.00000000000000, -3.47845948550071, 6.36317777566148, -8.54751527471874, 9.47693607801280, -8.81498681370155, 6.85401540936998, -4.39470996079559, 2.19611684890774, -0.75104302451432, 0.13149317958808 }, + { 0.98500175787242, -1.97000351574484, 0.98500175787242 }, + { 1.00000000000000, -1.96977855582618, 0.97022847566350 }, + }, + + { + 37800, 0, + { 0.10296717174470, -0.04877975583256, -0.02878009075237, -0.03519509188311, 0.02888717172493, -0.00609872684844, 0.00209851217112, 0.00911704668543, 0.01154404718589, -0.00630293688700, 0.00107527155228 }, + { 1.00000000000000, -2.64848054923531, 3.58406058405771, -3.83794914179161, 3.90142345804575, -3.50179818637243, 2.67085284083076, -1.82581142372418, 1.09530368139801, -0.47689017820395, 0.11171431535905 }, + { 0.98252400815195, -1.96504801630391, 0.98252400815195 }, + { 1.00000000000000, -1.96474258269041, 0.96535344991740 }, + }, + + { + 36000, 0, + { 0.11572297028613, -0.04120916051252, -0.04977731768022, -0.01047308680426, 0.00750863219157, 0.00055507694408, 0.00140344192886, 0.01286095246036, 0.00998223033885, -0.00725013810661, 0.00326503346879 }, + { 1.00000000000000, -2.43606802820871, 3.01907406973844, -2.90372016038192, 2.67947188094303, -2.17606479220391, 1.44912956803015, -0.87785765549050, 0.53592202672557, -0.26469344817509, 0.07495878059717 }, + { 0.98165826840326, -1.96331653680652, 0.98165826840326 }, + { 1.00000000000000, -1.96298008938934, 0.96365298422371 }, + }, + + { + 32000, 0, /* ORIGINAL */ + { 0.15457299681924, -0.09331049056315, -0.06247880153653, 0.02163541888798, -0.05588393329856, 0.04781476674921, 0.00222312597743, 0.03174092540049, -0.01390589421898, 0.00651420667831, -0.00881362733839 }, + { 1.00000000000000, -2.37898834973084, 2.84868151156327, -2.64577170229825, 2.23697657451713, -1.67148153367602, 1.00595954808547, -0.45953458054983, 0.16378164858596, -0.05032077717131, 0.02347897407020 }, + { 0.97938932735214, -1.95877865470428, 0.97938932735214 }, + { 1.00000000000000, -1.95835380975398, 0.95920349965459 }, + }, + + { + 28000, 0, + { 0.23882392323383, -0.22007791534089, -0.06014581950332, 0.05004458058021, -0.03293111254977, 0.02348678189717, 0.04290549799671, -0.00938141862174, 0.00015095146303, -0.00712601540885, -0.00626520210162 }, + { 1.00000000000000, -2.06894080899139, 1.76944699577212, -0.81404732584187, 0.25418286850232, -0.30340791669762, 0.35616884070937, -0.14967310591258, -0.07024154183279, 0.11078404345174, -0.03551838002425 }, + { 0.97647981663949, -1.95295963327897, 0.97647981663949 }, + { 1.00000000000000, -1.95240635772520, 0.95351290883275 }, + + }, + + { + 24000, 0, /* ORIGINAL */ + { 0.30296907319327, -0.22613988682123, -0.08587323730772, 0.03282930172664, -0.00915702933434, -0.02364141202522, -0.00584456039913, 0.06276101321749, -0.00000828086748, 0.00205861885564, -0.02950134983287 }, + { 1.00000000000000, -1.61273165137247, 1.07977492259970, -0.25656257754070, -0.16276719120440, -0.22638893773906, 0.39120800788284, -0.22138138954925, 0.04500235387352, 0.02005851806501, 0.00302439095741 }, + { 0.97531843204928, -1.95063686409857, 0.97531843204928 }, + { 1.00000000000000, -1.95002759149878, 0.95124613669835 }, + }, + + { + 22050, 0, /* ORIGINAL */ + { 0.33642304856132, -0.25572241425570, -0.11828570177555, 0.11921148675203, -0.07834489609479, -0.00469977914380, -0.00589500224440, 0.05724228140351, 0.00832043980773, -0.01635381384540, -0.01760176568150 }, + { 1.00000000000000, -1.49858979367799, 0.87350271418188, 0.12205022308084, -0.80774944671438, 0.47854794562326, -0.12453458140019, -0.04067510197014, 0.08333755284107, -0.04237348025746, 0.02977207319925 }, + { 0.97316523498161, -1.94633046996323, 0.97316523498161 }, + { 1.00000000000000, -1.94561023566527, 0.94705070426118 }, + }, + + { + 18900, 0, + { 0.38412657295385, -0.44533729608120, 0.20426638066221, -0.28031676047946, 0.31484202614802, -0.26078311203207, 0.12925201224848, -0.01141164696062, 0.03036522115769, -0.03776339305406, 0.00692036603586 }, + { 1.00000000000000, -1.74403915585708, 1.96686095832499, -2.10081452941881, 1.90753918182846, -1.83814263754422, 1.36971352214969, -0.77883609116398, 0.39266422457649, -0.12529383592986, 0.05424760697665 }, + { 0.96535326815829, -1.93070653631658, 0.96535326815829 }, + { 1.00000000000000, -1.92950577983524, 0.93190729279793 }, + }, + + { + 16000, 0, /* ORIGINAL */ + { 0.44915256608450, -0.14351757464547, -0.22784394429749, -0.01419140100551, 0.04078262797139, -0.12398163381748, 0.04097565135648, 0.10478503600251, -0.01863887810927, -0.03193428438915, 0.00541907748707 }, + { 1.00000000000000, -0.62820619233671, 0.29661783706366, -0.37256372942400, 0.00213767857124, -0.42029820170918, 0.22199650564824, 0.00613424350682, 0.06747620744683, 0.05784820375801, 0.03222754072173 }, + { 0.96454515552826, -1.92909031105652, 0.96454515552826 }, + { 1.00000000000000, -1.92783286977036, 0.93034775234268 }, + }, + + { + 12000, 0, /* ORIGINAL */ + { 0.56619470757641, -0.75464456939302, 0.16242137742230, 0.16744243493672, -0.18901604199609, 0.30931782841830, -0.27562961986224, 0.00647310677246, 0.08647503780351, -0.03788984554840, -0.00588215443421 }, + { 1.00000000000000, -1.04800335126349, 0.29156311971249, -0.26806001042947, 0.00819999645858, 0.45054734505008, -0.33032403314006, 0.06739368333110, -0.04784254229033, 0.01639907836189, 0.01807364323573 }, + { 0.96009142950541, -1.92018285901082, 0.96009142950541 }, + { 1.00000000000000, -1.91858953033784, 0.92177618768381 }, + }, + + { + 11025, 0, /* ORIGINAL */ + { 0.58100494960553, -0.53174909058578, -0.14289799034253, 0.17520704835522, 0.02377945217615, 0.15558449135573, -0.25344790059353, 0.01628462406333, 0.06920467763959, -0.03721611395801, -0.00749618797172 }, + { 1.00000000000000, -0.51035327095184, -0.31863563325245, -0.20256413484477, 0.14728154134330, 0.38952639978999, -0.23313271880868, -0.05246019024463, -0.02505961724053, 0.02442357316099, 0.01818801111503 }, + { 0.95856916599601, -1.91713833199203, 0.95856916599601 }, + { 1.00000000000000, -1.91542108074780, 0.91885558323625 }, + }, + + { + 8000, 0, /* ORIGINAL */ + { 0.53648789255105, -0.42163034350696, -0.00275953611929, 0.04267842219415, -0.10214864179676, 0.14590772289388, -0.02459864859345, -0.11202315195388, -0.04060034127000, 0.04788665548180, -0.02217936801134 }, + { 1.00000000000000, -0.25049871956020, -0.43193942311114, -0.03424681017675, -0.04678328784242, 0.26408300200955, 0.15113130533216, -0.17556493366449, -0.18823009262115, 0.05477720428674, 0.04704409688120 }, + { 0.94597685600279, -1.89195371200558, 0.94597685600279 }, + { 1.00000000000000, -1.88903307939452, 0.89487434461664 }, + }, + +}; + +#ifdef _MSC_VER +#pragma warning ( default : 4305 ) +#endif + +/* When calling this procedure, make sure that ip[-order] and op[-order] point to real data! */ + +static void +filter ( const flac_float_t* input, flac_float_t* output, size_t nSamples, const flac_float_t* a, const flac_float_t* b, size_t order, unsigned downsample ) +{ + double y; + size_t i; + size_t k; + + const flac_float_t* input_head = input; + const flac_float_t* input_tail; + + flac_float_t* output_head = output; + flac_float_t* output_tail; + + for ( i = 0; i < nSamples; i++, input_head += downsample, ++output_head ) { + + input_tail = input_head; + output_tail = output_head; + + y = *input_head * b[0]; + + for ( k = 1; k <= order; k++ ) { + input_tail -= downsample; + --output_tail; + y += *input_tail * b[k] - *output_tail * a[k]; + } + + output[i] = (flac_float_t)y; + } +} + +/* returns a INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if not */ + +static struct ReplayGainFilter* +CreateGainFilter ( long samplefreq ) +{ + unsigned i; + long maxrate = 0; + unsigned downsample = 1; + struct ReplayGainFilter* gainfilter = malloc(sizeof(*gainfilter)); + + if ( !gainfilter ) + return 0; + + while (1) { + for ( i = 0; i < sizeof(ReplayGainFilters)/sizeof(ReplayGainFilters[0]); ++i ) { + if (maxrate < ReplayGainFilters[i].rate) + maxrate = ReplayGainFilters[i].rate; + + if ( ReplayGainFilters[i].rate == samplefreq ) { + *gainfilter = ReplayGainFilters[i]; + gainfilter->downsample = downsample; + return gainfilter; + } + } + + if (samplefreq < maxrate) + break; + + while (samplefreq > maxrate) { + downsample *= 2; + samplefreq /= 2; + } + } + + free(gainfilter); + + return 0; +} + +static void* +ReallocateWindowBuffer(unsigned window_size, flac_float_t **window_buffer) +{ + *window_buffer = safe_realloc_(*window_buffer, sizeof(**window_buffer) * (window_size + MAX_ORDER)); + return *window_buffer; +} + +static int +ResetSampleFrequency ( long samplefreq ) { + int i; + + free(replaygainfilter); + + replaygainfilter = CreateGainFilter( samplefreq ); + + if ( ! replaygainfilter) + return INIT_GAIN_ANALYSIS_ERROR; + + sampleWindow = + (replaygainfilter->rate * RMS_WINDOW_TIME + 1000-1) / 1000; + + if ( ! ReallocateWindowBuffer(sampleWindow, &lstepbuf) || + ! ReallocateWindowBuffer(sampleWindow, &rstepbuf) || + ! ReallocateWindowBuffer(sampleWindow, &loutbuf) || + ! ReallocateWindowBuffer(sampleWindow, &routbuf) ) { + + return INIT_GAIN_ANALYSIS_ERROR; + } + + /* zero out initial values */ + for ( i = 0; i < MAX_ORDER; i++ ) + linprebuf[i] = lstepbuf[i] = loutbuf[i] = rinprebuf[i] = rstepbuf[i] = routbuf[i] = 0.; + + lsum = 0.; + rsum = 0.; + totsamp = 0; + + memset ( A, 0, sizeof(A) ); + + return INIT_GAIN_ANALYSIS_OK; +} + +int +ValidGainFrequency ( long samplefreq ) +{ + struct ReplayGainFilter* gainfilter = CreateGainFilter( samplefreq ); + + free(gainfilter); + + return gainfilter != 0; +} + +int +InitGainAnalysis ( long samplefreq ) +{ + if (ResetSampleFrequency(samplefreq) != INIT_GAIN_ANALYSIS_OK) { + return INIT_GAIN_ANALYSIS_ERROR; + } + + linpre = linprebuf + MAX_ORDER; + rinpre = rinprebuf + MAX_ORDER; + lstep = lstepbuf + MAX_ORDER; + rstep = rstepbuf + MAX_ORDER; + lout = loutbuf + MAX_ORDER; + rout = routbuf + MAX_ORDER; + + memset ( B, 0, sizeof(B) ); + + return INIT_GAIN_ANALYSIS_OK; +} + +/* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */ + +int +AnalyzeSamples ( const flac_float_t* left_samples, const flac_float_t* right_samples, size_t num_samples, int num_channels ) +{ + unsigned downsample = replaygainfilter->downsample; + const flac_float_t* curleft; + const flac_float_t* curright; + long prebufsamples; + long batchsamples; + long cursamples; + long cursamplepos; + int i; + + num_samples /= downsample; + + if ( num_samples == 0 ) + return GAIN_ANALYSIS_OK; + + cursamplepos = 0; + batchsamples = num_samples; + + switch ( num_channels) { + case 1: right_samples = left_samples; + case 2: break; + default: return GAIN_ANALYSIS_ERROR; + } + + prebufsamples = MAX_ORDER; + if ((size_t) prebufsamples > num_samples) + prebufsamples = num_samples; + + for ( i = 0; i < prebufsamples; ++i ) { + linprebuf[i+MAX_ORDER] = left_samples [i * downsample]; + rinprebuf[i+MAX_ORDER] = right_samples[i * downsample]; + } + + while ( batchsamples > 0 ) { + cursamples = batchsamples > (long)(sampleWindow-totsamp) ? (long)(sampleWindow - totsamp) : batchsamples; + if ( cursamplepos < MAX_ORDER ) { + downsample = 1; + curleft = linpre+cursamplepos; + curright = rinpre+cursamplepos; + if (cursamples > MAX_ORDER - cursamplepos ) + cursamples = MAX_ORDER - cursamplepos; + } + else { + downsample = replaygainfilter->downsample; + curleft = left_samples + cursamplepos * downsample; + curright = right_samples + cursamplepos * downsample; + } + + filter ( curleft , lstep + totsamp, cursamples, replaygainfilter->AYule, replaygainfilter->BYule, YULE_ORDER, downsample ); + filter ( curright, rstep + totsamp, cursamples, replaygainfilter->AYule, replaygainfilter->BYule, YULE_ORDER, downsample ); + + filter ( lstep + totsamp, lout + totsamp, cursamples, replaygainfilter->AButter, replaygainfilter->BButter, BUTTER_ORDER, 1 ); + filter ( rstep + totsamp, rout + totsamp, cursamples, replaygainfilter->AButter, replaygainfilter->BButter, BUTTER_ORDER, 1 ); + + for ( i = 0; i < cursamples; i++ ) { /* Get the squared values */ + lsum += lout [totsamp+i] * lout [totsamp+i]; + rsum += rout [totsamp+i] * rout [totsamp+i]; + } + + batchsamples -= cursamples; + cursamplepos += cursamples; + totsamp += cursamples; + if ( totsamp == sampleWindow ) { /* Get the Root Mean Square (RMS) for this set of samples */ + double val = STEPS_per_dB * 10. * log10 ( (lsum+rsum) / totsamp * 0.5 + 1.e-37 ); + int ival = (int) val; + if ( ival < 0 ) ival = 0; + if ( ival >= (int)(sizeof(A)/sizeof(*A)) ) ival = (int)(sizeof(A)/sizeof(*A)) - 1; + A [ival]++; + lsum = rsum = 0.; + memmove ( loutbuf , loutbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) ); + memmove ( routbuf , routbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) ); + memmove ( lstepbuf, lstepbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) ); + memmove ( rstepbuf, rstepbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) ); + totsamp = 0; + } + if ( totsamp > sampleWindow ) /* somehow I really screwed up: Error in programming! Contact author about totsamp > sampleWindow */ + return GAIN_ANALYSIS_ERROR; + } + + if ( num_samples < MAX_ORDER ) { + memmove ( linprebuf, linprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(flac_float_t) ); + memmove ( rinprebuf, rinprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(flac_float_t) ); + memcpy ( linprebuf + MAX_ORDER - num_samples, left_samples, num_samples * sizeof(flac_float_t) ); + memcpy ( rinprebuf + MAX_ORDER - num_samples, right_samples, num_samples * sizeof(flac_float_t) ); + } + else { + downsample = replaygainfilter->downsample; + + left_samples += (num_samples - MAX_ORDER) * downsample; + right_samples += (num_samples - MAX_ORDER) * downsample; + + for ( i = 0; i < MAX_ORDER; ++i ) { + linprebuf[i] = left_samples [i * downsample]; + rinprebuf[i] = right_samples[i * downsample]; + } + } + + return GAIN_ANALYSIS_OK; +} + + +static flac_float_t +analyzeResult ( uint32_t* Array, size_t len ) +{ + uint32_t elems; + int32_t upper; + size_t i; + + elems = 0; + for ( i = 0; i < len; i++ ) + elems += Array[i]; + if ( elems == 0 ) + return GAIN_NOT_ENOUGH_SAMPLES; + +/* workaround for GCC bug #61423: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61423 */ +#if 0 + upper = (int32_t) ceil (elems * (1. - RMS_PERCENTILE)); +#else + upper = (int32_t) (elems / 20 + ((elems % 20) ? 1 : 0)); +#endif + for ( i = len; i-- > 0; ) { + if ( (upper -= Array[i]) <= 0 ) + break; + } + + return (flac_float_t) ((flac_float_t)PINK_REF - (flac_float_t)i / (flac_float_t)STEPS_per_dB); +} + + +flac_float_t +GetTitleGain ( void ) +{ + flac_float_t retval; + unsigned int i; + + retval = analyzeResult ( A, sizeof(A)/sizeof(*A) ); + + for ( i = 0; i < sizeof(A)/sizeof(*A); i++ ) { + B[i] += A[i]; + A[i] = 0; + } + + for ( i = 0; i < MAX_ORDER; i++ ) + linprebuf[i] = lstepbuf[i] = loutbuf[i] = rinprebuf[i] = rstepbuf[i] = routbuf[i] = 0.f; + + totsamp = 0; + lsum = rsum = 0.; + return retval; +} + + +flac_float_t +GetAlbumGain ( void ) +{ + return analyzeResult ( B, sizeof(B)/sizeof(*B) ); +} + +/* end of replaygain_analysis.c */ diff --git a/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcproj b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcproj new file mode 100644 index 0000000..152d827 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcproj @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="replaygain_analysis_static"
+ ProjectGUID="{4cefbc89-c215-11db-8314-0800200c9a66}"
+ RootNamespace="replaygain_analysis_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\..\include\share\replaygain_analysis.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\replaygain_analysis.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcxproj b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcxproj new file mode 100644 index 0000000..6824f81 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcxproj @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc89-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>replaygain_analysis_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\replaygain_analysis.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="replaygain_analysis.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcxproj.filters b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcxproj.filters new file mode 100644 index 0000000..f1207d3 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_analysis/replaygain_analysis_static.vcxproj.filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{9e16659d-14e5-4477-be88-76193fff5d31}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\replaygain_analysis.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="replaygain_analysis.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/replaygain_synthesis/Makefile.lite b/deps/flac-1.3.2/src/share/replaygain_synthesis/Makefile.lite new file mode 100644 index 0000000..a944234 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_synthesis/Makefile.lite @@ -0,0 +1,15 @@ +# +# GNU makefile +# + +topdir = ../../.. + +LIB_NAME = libreplaygain_synthesis +INCLUDES = -I./include -I$(topdir)/include + +SRCS_C = \ + replaygain_synthesis.c + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis.c b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis.c new file mode 100644 index 0000000..b7d227e --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis.c @@ -0,0 +1,423 @@ +/* replaygain_synthesis - Routines for applying ReplayGain to a signal + * Copyright (C) 2002-2009 Josh Coalson + * Copyright (C) 2011-2016 Xiph.Org Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +/* + * This is an aggregation of pieces of code from John Edwards' WaveGain + * program. Mostly cosmetic changes were made; otherwise, the dithering + * code is almost untouched and the gain processing was converted from + * processing a whole file to processing chunks of samples. + * + * The original copyright notices for WaveGain's dither.c and wavegain.c + * appear below: + */ +/* + * (c) 2002 John Edwards + * mostly lifted from work by Frank Klemm + * random functions for dithering. + */ +/* + * Copyright (C) 2002 John Edwards + * Additional code by Magnus Holmgren and Gian-Carlo Pascutto + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> /* for memset() */ +#include <math.h> +#include "share/replaygain_synthesis.h" +#include "FLAC/assert.h" + +#define FLAC__I64L(x) x##LL + + +/* + * the following is based on parts of dither.c + */ + + +/* + * This is a simple random number generator with good quality for audio purposes. + * It consists of two polycounters with opposite rotation direction and different + * periods. The periods are coprime, so the total period is the product of both. + * + * ------------------------------------------------------------------------------------------------- + * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| + * | ------------------------------------------------------------------------------------------------- + * | | | | | | | + * | +--+--+--+-XOR-+--------+ + * | | + * +--------------------------------------------------------------------------------------+ + * + * ------------------------------------------------------------------------------------------------- + * |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+ + * ------------------------------------------------------------------------------------------------- | + * | | | | | + * +--+----XOR----+--+ | + * | | + * +----------------------------------------------------------------------------------------+ + * + * + * The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481, + * which gives a period of 18.410.713.077.675.721.215. The result is the + * XORed values of both generators. + */ + +static unsigned int random_int_(void) +{ + static const unsigned char parity_[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 + }; + static unsigned int r1_ = 1; + static unsigned int r2_ = 1; + + unsigned int t1, t2, t3, t4; + + /* Parity calculation is done via table lookup, this is also available + * on CPUs without parity, can be implemented in C and avoid unpredictable + * jumps and slow rotate through the carry flag operations. + */ + t3 = t1 = r1_; t4 = t2 = r2_; + t1 &= 0xF5; t2 >>= 25; + t1 = parity_[t1]; t2 &= 0x63; + t1 <<= 31; t2 = parity_[t2]; + + return (r1_ = (t3 >> 1) | t1 ) ^ (r2_ = (t4 + t4) | t2 ); +} + +/* gives a equal distributed random number */ +/* between -2^31*mult and +2^31*mult */ +static double random_equi_(double mult) +{ + return mult * (int) random_int_(); +} + +/* gives a triangular distributed random number */ +/* between -2^32*mult and +2^32*mult */ +static double random_triangular_(double mult) +{ + return mult * ( (double) (int) random_int_() + (double) (int) random_int_() ); +} + + +static const float F44_0 [16 + 32] = { + (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, + (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, + + (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, + (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, + + (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, + (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0 +}; + + +static const float F44_1 [16 + 32] = { /* SNR(w) = 4.843163 dB, SNR = -3.192134 dB */ + (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833, + (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967, + (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116, + (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024, + + (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833, + (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967, + (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116, + (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024, + + (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833, + (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967, + (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116, + (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024, +}; + + +static const float F44_2 [16 + 32] = { /* SNR(w) = 10.060213 dB, SNR = -12.766730 dB */ + (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437, + (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264, + (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562, + (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816, + + (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437, + (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264, + (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562, + (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816, + + (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437, + (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264, + (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562, + (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816, +}; + + +static const float F44_3 [16 + 32] = { /* SNR(w) = 15.382598 dB, SNR = -29.402334 dB */ + (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515, + (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785, + (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927, + (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099, + + (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515, + (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785, + (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927, + (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099, + + (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515, + (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785, + (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927, + (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099 +}; + + +static double scalar16_(const float* x, const float* y) +{ + return + x[ 0]*y[ 0] + x[ 1]*y[ 1] + x[ 2]*y[ 2] + x[ 3]*y[ 3] + + x[ 4]*y[ 4] + x[ 5]*y[ 5] + x[ 6]*y[ 6] + x[ 7]*y[ 7] + + x[ 8]*y[ 8] + x[ 9]*y[ 9] + x[10]*y[10] + x[11]*y[11] + + x[12]*y[12] + x[13]*y[13] + x[14]*y[14] + x[15]*y[15]; +} + + +void FLAC__replaygain_synthesis__init_dither_context(DitherContext *d, int bits, int shapingtype) +{ + static unsigned char default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67, 0, 0 }; + static const float* F [] = { F44_0, F44_1, F44_2, F44_3 }; + + int indx; + + if (shapingtype < 0) shapingtype = 0; + if (shapingtype > 3) shapingtype = 3; + d->ShapingType = (NoiseShaping)shapingtype; + indx = bits - 11 - shapingtype; + if (indx < 0) indx = 0; + if (indx > 9) indx = 9; + + memset ( d->ErrorHistory , 0, sizeof (d->ErrorHistory ) ); + memset ( d->DitherHistory, 0, sizeof (d->DitherHistory) ); + + d->FilterCoeff = F [shapingtype]; + d->Mask = ((FLAC__uint64)-1) << (32 - bits); + d->Add = 0.5 * ((1L << (32 - bits)) - 1); + d->Dither = 0.01f*default_dither[indx] / (((FLAC__int64)1) << bits); + d->LastHistoryIndex = 0; +} + +/* + * the following is based on parts of wavegain.c + */ + +static FLAC__int64 dither_output_(DitherContext *d, FLAC__bool do_dithering, int shapingtype, int i, double Sum, int k) +{ + union { + double d; + FLAC__int64 i; + } doubletmp; + double Sum2; + FLAC__int64 val; + +#define ROUND64(x) ( doubletmp.d = (x) + d->Add + (FLAC__int64)FLAC__I64L(0x001FFFFD80000000), doubletmp.i - (FLAC__int64)FLAC__I64L(0x433FFFFD80000000) ) + + if(do_dithering) { + if(shapingtype == 0) { + double tmp = random_equi_(d->Dither); + Sum2 = tmp - d->LastRandomNumber [k]; + d->LastRandomNumber [k] = (int)tmp; + Sum2 = Sum += Sum2; + val = ROUND64(Sum2) & d->Mask; + } + else { + Sum2 = random_triangular_(d->Dither) - scalar16_(d->DitherHistory[k], d->FilterCoeff + i); + Sum += d->DitherHistory [k] [(-1-i)&15] = (float)Sum2; + Sum2 = Sum + scalar16_(d->ErrorHistory [k], d->FilterCoeff + i); + val = ROUND64(Sum2) & d->Mask; + d->ErrorHistory [k] [(-1-i)&15] = (float)(Sum - val); + } + return val; + } + else + return ROUND64(Sum); + +#undef ROUND64 +} + +#if 0 + float peak = 0.f, + new_peak, + factor_clip + double scale, + dB; + + ... + + peak is in the range -32768.0 .. 32767.0 + + /* calculate factors for ReplayGain and ClippingPrevention */ + *track_gain = GetTitleGain() + settings->man_gain; + scale = (float) pow(10., *track_gain * 0.05); + if(settings->clip_prev) { + factor_clip = (float) (32767./( peak + 1)); + if(scale < factor_clip) + factor_clip = 1.f; + else + factor_clip /= scale; + scale *= factor_clip; + } + new_peak = (float) peak * scale; + + dB = 20. * log10(scale); + *track_gain = (float) dB; + + const double scale = pow(10., (double)gain * 0.05); +#endif + + +size_t FLAC__replaygain_synthesis__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, FLAC__bool unsigned_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const double scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context) +{ + static const FLAC__int64 hard_clip_factors_[33] = { + 0, /* 0 bits-per-sample (not supported) */ + 0, /* 1 bits-per-sample (not supported) */ + 0, /* 2 bits-per-sample (not supported) */ + 0, /* 3 bits-per-sample (not supported) */ + -8, /* 4 bits-per-sample */ + -16, /* 5 bits-per-sample */ + -32, /* 6 bits-per-sample */ + -64, /* 7 bits-per-sample */ + -128, /* 8 bits-per-sample */ + -256, /* 9 bits-per-sample */ + -512, /* 10 bits-per-sample */ + -1024, /* 11 bits-per-sample */ + -2048, /* 12 bits-per-sample */ + -4096, /* 13 bits-per-sample */ + -8192, /* 14 bits-per-sample */ + -16384, /* 15 bits-per-sample */ + -32768, /* 16 bits-per-sample */ + -65536, /* 17 bits-per-sample */ + -131072, /* 18 bits-per-sample */ + -262144, /* 19 bits-per-sample */ + -524288, /* 20 bits-per-sample */ + -1048576, /* 21 bits-per-sample */ + -2097152, /* 22 bits-per-sample */ + -4194304, /* 23 bits-per-sample */ + -8388608, /* 24 bits-per-sample */ + -16777216, /* 25 bits-per-sample */ + -33554432, /* 26 bits-per-sample */ + -67108864, /* 27 bits-per-sample */ + -134217728, /* 28 bits-per-sample */ + -268435456, /* 29 bits-per-sample */ + -536870912, /* 30 bits-per-sample */ + -1073741824, /* 31 bits-per-sample */ + (FLAC__int64)(-1073741824) * 2 /* 32 bits-per-sample */ + }; + const FLAC__int32 conv_shift = 32 - target_bps; + const FLAC__int64 hard_clip_factor = hard_clip_factors_[target_bps]; + /* + * The integer input coming in has a varying range based on the + * source_bps. We want to normalize it to [-1.0, 1.0) so instead + * of doing two multiplies on each sample, we just multiple + * 'scale' by 1/(2^(source_bps-1)) + */ + const double multi_scale = scale / (double)(1u << (source_bps-1)); + + FLAC__byte * const start = data_out; + unsigned i, channel; + const FLAC__int32 *input_; + double sample; + const unsigned bytes_per_sample = target_bps / 8; + const unsigned last_history_index = dither_context->LastHistoryIndex; + NoiseShaping noise_shaping = dither_context->ShapingType; + FLAC__int64 val64; + FLAC__int32 val32; + FLAC__int32 uval32; + const FLAC__uint32 twiggle = 1u << (target_bps - 1); + + FLAC__ASSERT(channels > 0 && channels <= FLAC_SHARE__MAX_SUPPORTED_CHANNELS); + FLAC__ASSERT(source_bps >= 4); + FLAC__ASSERT(target_bps >= 4); + FLAC__ASSERT(source_bps <= 32); + FLAC__ASSERT(target_bps < 32); + FLAC__ASSERT((target_bps & 7) == 0); + + for(channel = 0; channel < channels; channel++) { + const unsigned incr = bytes_per_sample * channels; + data_out = start + bytes_per_sample * channel; + input_ = input[channel]; + for(i = 0; i < wide_samples; i++, data_out += incr) { + sample = (double)input_[i] * multi_scale; + + if(hard_limit) { + /* hard 6dB limiting */ + if(sample < -0.5) + sample = tanh((sample + 0.5) / (1-0.5)) * (1-0.5) - 0.5; + else if(sample > 0.5) + sample = tanh((sample - 0.5) / (1-0.5)) * (1-0.5) + 0.5; + } + sample *= 2147483647.; + + val64 = dither_output_(dither_context, do_dithering, noise_shaping, (i + last_history_index) % 32, sample, channel) >> conv_shift; + + val32 = (FLAC__int32)val64; + if(val64 >= -hard_clip_factor) + val32 = (FLAC__int32)(-(hard_clip_factor+1)); + else if(val64 < hard_clip_factor) + val32 = (FLAC__int32)hard_clip_factor; + + uval32 = (FLAC__uint32)val32; + if (unsigned_data_out) + uval32 ^= twiggle; + + if (little_endian_data_out) { + switch(target_bps) { + case 24: + data_out[2] = (FLAC__byte)(uval32 >> 16); + /* fall through */ + case 16: + data_out[1] = (FLAC__byte)(uval32 >> 8); + /* fall through */ + case 8: + data_out[0] = (FLAC__byte)uval32; + break; + } + } + else { + switch(target_bps) { + case 24: + data_out[0] = (FLAC__byte)(uval32 >> 16); + data_out[1] = (FLAC__byte)(uval32 >> 8); + data_out[2] = (FLAC__byte)uval32; + break; + case 16: + data_out[0] = (FLAC__byte)(uval32 >> 8); + data_out[1] = (FLAC__byte)uval32; + break; + case 8: + data_out[0] = (FLAC__byte)uval32; + break; + } + } + } + } + dither_context->LastHistoryIndex = (last_history_index + wide_samples) % 32; + + return wide_samples * channels * (target_bps/8); +} diff --git a/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcproj b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcproj new file mode 100644 index 0000000..1e28a9b --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcproj @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="replaygain_synthesis_static"
+ ProjectGUID="{4cefbc8a-c215-11db-8314-0800200c9a66}"
+ RootNamespace="replaygain_synthesis_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\..\include\share\replaygain_synthesis.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\replaygain_synthesis.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcxproj b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcxproj new file mode 100644 index 0000000..b8379c0 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcxproj @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc8a-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>replaygain_synthesis_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\replaygain_synthesis.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="replaygain_synthesis.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters new file mode 100644 index 0000000..ace3776 --- /dev/null +++ b/deps/flac-1.3.2/src/share/replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{47ae72f8-630b-4044-b8ce-f4d560d70f4f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\replaygain_synthesis.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="replaygain_synthesis.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/utf8/Makefile.lite b/deps/flac-1.3.2/src/share/utf8/Makefile.lite new file mode 100644 index 0000000..ad50492 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/Makefile.lite @@ -0,0 +1,25 @@ +# +# GNU makefile +# + +topdir = ../../.. +libdir = $(topdir)/objs/$(BUILD)/lib + +LIB_NAME = libutf8 + +ifeq ($(OS),Darwin) + EXPLICIT_LIBS = $(libdir)/libgrabbag.a $(ICONV_LIBS) +else + LIBS = -lgrabbag $(ICONV_LIBS) +endif + +INCLUDES = -I$(topdir)/include + +SRCS_C = \ + charset.c \ + iconvert.c \ + utf8.c + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/share/utf8/charmaps.h b/deps/flac-1.3.2/src/share/utf8/charmaps.h new file mode 100644 index 0000000..690d890 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/charmaps.h @@ -0,0 +1,57 @@ + +/* + * If you need to generate more maps, use makemap.c on a system + * with a decent iconv. + */ + +static const unsigned short mapping_iso_8859_2[256] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +static struct { + const char *name; + const unsigned short *map; + struct charset *charset; +} maps[] = { + { "ISO-8859-2", mapping_iso_8859_2, 0 }, + { 0, 0, 0 } +}; + +static const struct { + const char *bad; + const char *good; +} names[] = { + { "ANSI_X3.4-1968", "us-ascii" }, + { 0, 0 } +}; diff --git a/deps/flac-1.3.2/src/share/utf8/charset.c b/deps/flac-1.3.2/src/share/utf8/charset.c new file mode 100644 index 0000000..5a2a6e4 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/charset.c @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * See the corresponding header file for a description of the functions + * that this file provides. + * + * This was first written for Ogg Vorbis but could be of general use. + * + * The only deliberate assumption about data sizes is that a short has + * at least 16 bits, but this code has only been tested on systems with + * 8-bit char, 16-bit short and 32-bit int. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if !defined _WIN32 && !defined HAVE_ICONV /* should be && defined USE_CHARSET_CONVERT */ + +#include <stdlib.h> + +#include "share/alloc.h" +#include "charset.h" + +#include "charmaps.h" + +/* + * This is like the standard strcasecmp, but it does not depend + * on the locale. Locale-dependent functions can be dangerous: + * we once had a bug involving strcasecmp("iso", "ISO") in a + * Turkish locale! + * + * (I'm not really sure what the official standard says + * about the sign of strcasecmp("Z", "["), but usually + * we're only interested in whether it's zero.) + */ + +static int ascii_strcasecmp(const char *s1, const char *s2) +{ + char c1, c2; + + for (;; s1++, s2++) { + if (!*s1 || !*s2) + break; + if (*s1 == *s2) + continue; + c1 = *s1; + if ('a' <= c1 && c1 <= 'z') + c1 += 'A' - 'a'; + c2 = *s2; + if ('a' <= c2 && c2 <= 'z') + c2 += 'A' - 'a'; + if (c1 != c2) + break; + } + return (unsigned char)*s1 - (unsigned char)*s2; +} + +/* + * UTF-8 equivalents of the C library's wctomb() and mbtowc(). + */ + +int utf8_mbtowc(int *pwc, const char *s, size_t n) +{ + unsigned char c; + int wc, i, k; + + if (!n || !s) + return 0; + + c = *s; + if (c < 0x80) { + if (pwc) + *pwc = c; + return c ? 1 : 0; + } + else if (c < 0xc2) + return -1; + else if (c < 0xe0) { + if (n >= 2 && (s[1] & 0xc0) == 0x80) { + if (pwc) + *pwc = ((c & 0x1f) << 6) | (s[1] & 0x3f); + return 2; + } + else + return -1; + } + else if (c < 0xf0) + k = 3; + else if (c < 0xf8) + k = 4; + else if (c < 0xfc) + k = 5; + else if (c < 0xfe) + k = 6; + else + return -1; + + if (n < (size_t)k) + return -1; + wc = *s++ & ((1 << (7 - k)) - 1); + for (i = 1; i < k; i++) { + if ((*s & 0xc0) != 0x80) + return -1; + wc = (wc << 6) | (*s++ & 0x3f); + } + if (wc < (1 << (5 * k - 4))) + return -1; + if (pwc) + *pwc = wc; + return k; +} + +int utf8_wctomb(char *s, int wc1) +{ + unsigned int wc = wc1; + + if (!s) + return 0; + if (wc < (1u << 7)) { + *s++ = wc; + return 1; + } + else if (wc < (1u << 11)) { + *s++ = 0xc0 | (wc >> 6); + *s++ = 0x80 | (wc & 0x3f); + return 2; + } + else if (wc < (1u << 16)) { + *s++ = 0xe0 | (wc >> 12); + *s++ = 0x80 | ((wc >> 6) & 0x3f); + *s++ = 0x80 | (wc & 0x3f); + return 3; + } + else if (wc < (1u << 21)) { + *s++ = 0xf0 | (wc >> 18); + *s++ = 0x80 | ((wc >> 12) & 0x3f); + *s++ = 0x80 | ((wc >> 6) & 0x3f); + *s++ = 0x80 | (wc & 0x3f); + return 4; + } + else if (wc < (1u << 26)) { + *s++ = 0xf8 | (wc >> 24); + *s++ = 0x80 | ((wc >> 18) & 0x3f); + *s++ = 0x80 | ((wc >> 12) & 0x3f); + *s++ = 0x80 | ((wc >> 6) & 0x3f); + *s++ = 0x80 | (wc & 0x3f); + return 5; + } + else if (wc < (1u << 31)) { + *s++ = 0xfc | (wc >> 30); + *s++ = 0x80 | ((wc >> 24) & 0x3f); + *s++ = 0x80 | ((wc >> 18) & 0x3f); + *s++ = 0x80 | ((wc >> 12) & 0x3f); + *s++ = 0x80 | ((wc >> 6) & 0x3f); + *s++ = 0x80 | (wc & 0x3f); + return 6; + } + else + return -1; +} + +/* + * The charset "object" and methods. + */ + +struct charset { + int max; + int (*mbtowc)(void *table, int *pwc, const char *s, size_t n); + int (*wctomb)(void *table, char *s, int wc); + void *map; +}; + +int charset_mbtowc(struct charset *charset, int *pwc, const char *s, size_t n) +{ + return (*charset->mbtowc)(charset->map, pwc, s, n); +} + +int charset_wctomb(struct charset *charset, char *s, int wc) +{ + return (*charset->wctomb)(charset->map, s, wc); +} + +int charset_max(struct charset *charset) +{ + return charset->max; +} + +/* + * Implementation of UTF-8. + */ + +static int mbtowc_utf8(void *map, int *pwc, const char *s, size_t n) +{ + (void)map; + return utf8_mbtowc(pwc, s, n); +} + +static int wctomb_utf8(void *map, char *s, int wc) +{ + (void)map; + return utf8_wctomb(s, wc); +} + +/* + * Implementation of US-ASCII. + * Probably on most architectures this compiles to less than 256 bytes + * of code, so we can save space by not having a table for this one. + */ + +static int mbtowc_ascii(void *map, int *pwc, const char *s, size_t n) +{ + int wc; + + (void)map; + if (!n || !s) + return 0; + wc = (unsigned char)*s; + if (wc & ~0x7f) + return -1; + if (pwc) + *pwc = wc; + return wc ? 1 : 0; +} + +static int wctomb_ascii(void *map, char *s, int wc) +{ + (void)map; + if (!s) + return 0; + if (wc & ~0x7f) + return -1; + *s = wc; + return 1; +} + +/* + * Implementation of ISO-8859-1. + * Probably on most architectures this compiles to less than 256 bytes + * of code, so we can save space by not having a table for this one. + */ + +static int mbtowc_iso1(void *map, int *pwc, const char *s, size_t n) +{ + int wc; + + (void)map; + if (!n || !s) + return 0; + wc = (unsigned char)*s; + if (wc & ~0xff) + return -1; + if (pwc) + *pwc = wc; + return wc ? 1 : 0; +} + +static int wctomb_iso1(void *map, char *s, int wc) +{ + (void)map; + if (!s) + return 0; + if (wc & ~0xff) + return -1; + *s = wc; + return 1; +} + +/* + * Implementation of any 8-bit charset. + */ + +struct map { + const unsigned short *from; + struct inverse_map *to; +}; + +static int mbtowc_8bit(void *map1, int *pwc, const char *s, size_t n) +{ + struct map *map = map1; + unsigned short wc; + + if (!n || !s) + return 0; + wc = map->from[(unsigned char)*s]; + if (wc == 0xffff) + return -1; + if (pwc) + *pwc = (int)wc; + return wc ? 1 : 0; +} + +/* + * For the inverse map we use a hash table, which has the advantages + * of small constant memory requirement and simple memory allocation, + * but the disadvantage of slow conversion in the worst case. + * If you need real-time performance while letting a potentially + * malicious user define their own map, then the method used in + * linux/drivers/char/consolemap.c would be more appropriate. + */ + +struct inverse_map { + unsigned char first[256]; + unsigned char next[256]; +}; + +/* + * The simple hash is good enough for this application. + * Use the alternative trivial hashes for testing. + */ +#define HASH(i) ((i) & 0xff) +/* #define HASH(i) 0 */ +/* #define HASH(i) 99 */ + +static struct inverse_map *make_inverse_map(const unsigned short *from) +{ + struct inverse_map *to; + char used[256]; + int i, j, k; + + to = malloc(sizeof(struct inverse_map)); + if (!to) + return 0; + for (i = 0; i < 256; i++) + to->first[i] = to->next[i] = used[i] = 0; + for (i = 255; i >= 0; i--) + if (from[i] != 0xffff) { + k = HASH(from[i]); + to->next[i] = to->first[k]; + to->first[k] = i; + used[k] = 1; + } + + /* Point the empty buckets at an empty list. */ + for (i = 0; i < 256; i++) + if (!to->next[i]) + break; + if (i < 256) + for (j = 0; j < 256; j++) + if (!used[j]) + to->first[j] = i; + + return to; +} + +static int wctomb_8bit(void *map1, char *s, int wc1) +{ + struct map *map = map1; + unsigned short wc = wc1; + int i; + + if (!s) + return 0; + + if (wc1 & ~0xffff) + return -1; + + if (1) /* Change 1 to 0 to test the case where malloc fails. */ + if (!map->to) + map->to = make_inverse_map(map->from); + + if (map->to) { + /* Use the inverse map. */ + i = map->to->first[HASH(wc)]; + for (;;) { + if (map->from[i] == wc) { + *s = i; + return 1; + } + if (!(i = map->to->next[i])) + break; + } + } + else { + /* We don't have an inverse map, so do a linear search. */ + for (i = 0; i < 256; i++) + if (map->from[i] == wc) { + *s = i; + return 1; + } + } + + return -1; +} + +/* + * The "constructor" charset_find(). + */ + +struct charset charset_utf8 = { + 6, + &mbtowc_utf8, + &wctomb_utf8, + 0 +}; + +struct charset charset_iso1 = { + 1, + &mbtowc_iso1, + &wctomb_iso1, + 0 +}; + +struct charset charset_ascii = { + 1, + &mbtowc_ascii, + &wctomb_ascii, + 0 +}; + +struct charset *charset_find(const char *code) +{ + int i; + + /* Find good (MIME) name. */ + for (i = 0; names[i].bad; i++) + if (!ascii_strcasecmp(code, names[i].bad)) { + code = names[i].good; + break; + } + + /* Recognise some charsets for which we avoid using a table. */ + if (!ascii_strcasecmp(code, "UTF-8")) + return &charset_utf8; + if (!ascii_strcasecmp(code, "US-ASCII")) + return &charset_ascii; + if (!ascii_strcasecmp(code, "ISO-8859-1")) + return &charset_iso1; + + /* Look for a mapping for a simple 8-bit encoding. */ + for (i = 0; maps[i].name; i++) + if (!ascii_strcasecmp(code, maps[i].name)) { + if (!maps[i].charset) { + maps[i].charset = malloc(sizeof(struct charset)); + if (maps[i].charset) { + struct map *map = malloc(sizeof(struct map)); + if (!map) { + free(maps[i].charset); + maps[i].charset = 0; + } + else { + maps[i].charset->max = 1; + maps[i].charset->mbtowc = &mbtowc_8bit; + maps[i].charset->wctomb = &wctomb_8bit; + maps[i].charset->map = map; + map->from = maps[i].map; + map->to = 0; /* inverse mapping is created when required */ + } + } + } + return maps[i].charset; + } + + return 0; +} + +/* + * Function to convert a buffer from one encoding to another. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * Each of TO and TOLEN may be zero, if the result is not needed. + * The output buffer is null-terminated, so it is all right to + * use charset_convert(fromcode, tocode, s, strlen(s), &t, 0). + */ + +int charset_convert(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen) +{ + int ret = 0; + struct charset *charset1, *charset2; + char *tobuf, *p, *newbuf; + int i, j, wc; + + charset1 = charset_find(fromcode); + charset2 = charset_find(tocode); + if (!charset1 || !charset2 ) + return -1; + + tobuf = safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1); + if (!tobuf) + return -2; + + for (p = tobuf; fromlen; from += i, fromlen -= i, p += j) { + i = charset_mbtowc(charset1, &wc, from, fromlen); + if (!i) + i = 1; + else if (i == -1) { + i = 1; + wc = '#'; + ret = 2; + } + j = charset_wctomb(charset2, p, wc); + if (j == -1) { + if (!ret) + ret = 1; + j = charset_wctomb(charset2, p, '?'); + if (j == -1) + j = 0; + } + } + + if (tolen) + *tolen = p - tobuf; + *p++ = '\0'; + if (to) { + newbuf = realloc(tobuf, p - tobuf); + *to = newbuf ? newbuf : tobuf; + } + else + free(tobuf); + + return ret; +} + +#endif /* USE_CHARSET_ICONV */ diff --git a/deps/flac-1.3.2/src/share/utf8/charset.h b/deps/flac-1.3.2/src/share/utf8/charset.h new file mode 100644 index 0000000..ea8e31e --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/charset.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdlib.h> + +/* + * These functions are like the C library's mbtowc() and wctomb(), + * but instead of depending on the locale they always work in UTF-8, + * and they use int instead of wchar_t. + */ + +int utf8_mbtowc(int *pwc, const char *s, size_t n); +int utf8_wctomb(char *s, int wc); + +/* + * This is an object-oriented version of mbtowc() and wctomb(). + * The caller first uses charset_find() to get a pointer to struct + * charset, then uses the mbtowc() and wctomb() methods on it. + * The function charset_max() gives the maximum length of a + * multibyte character in that encoding. + * This API is only appropriate for stateless encodings like UTF-8 + * or ISO-8859-3, but I have no intention of implementing anything + * other than UTF-8 and 8-bit encodings. + * + * MINOR BUG: If there is no memory charset_find() may return 0 and + * there is no way to distinguish this case from an unknown encoding. + */ + +struct charset; + +struct charset *charset_find(const char *code); + +int charset_mbtowc(struct charset *charset, int *pwc, const char *s, size_t n); +int charset_wctomb(struct charset *charset, char *s, int wc); +int charset_max(struct charset *charset); + +/* + * Function to convert a buffer from one encoding to another. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * Each of TO and TOLEN may be zero if the result is not wanted. + * The input or output may contain null bytes, but the output + * buffer is also null-terminated, so it is all right to + * use charset_convert(fromcode, tocode, s, strlen(s), &t, 0). + * + * Return value: + * + * -2 : memory allocation failed + * -1 : unknown encoding + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + */ + +int charset_convert(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen); diff --git a/deps/flac-1.3.2/src/share/utf8/charset_test.c b/deps/flac-1.3.2/src/share/utf8/charset_test.c new file mode 100644 index 0000000..225a673 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/charset_test.c @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <string.h> + +#include "charset.h" + +void test_any(struct charset *charset) +{ + int wc; + char s[2]; + + assert(charset); + + /* Decoder */ + + assert(charset_mbtowc(charset, 0, 0, 0) == 0); + assert(charset_mbtowc(charset, 0, 0, 1) == 0); + assert(charset_mbtowc(charset, 0, (char *)(-1), 0) == 0); + + assert(charset_mbtowc(charset, 0, "a", 0) == 0); + assert(charset_mbtowc(charset, 0, "", 1) == 0); + assert(charset_mbtowc(charset, 0, "b", 1) == 1); + assert(charset_mbtowc(charset, 0, "", 2) == 0); + assert(charset_mbtowc(charset, 0, "c", 2) == 1); + + wc = 'x'; + assert(charset_mbtowc(charset, &wc, "a", 0) == 0 && wc == 'x'); + assert(charset_mbtowc(charset, &wc, "", 1) == 0 && wc == 0); + assert(charset_mbtowc(charset, &wc, "b", 1) == 1 && wc == 'b'); + assert(charset_mbtowc(charset, &wc, "", 2) == 0 && wc == 0); + assert(charset_mbtowc(charset, &wc, "c", 2) == 1 && wc == 'c'); + + /* Encoder */ + + assert(charset_wctomb(charset, 0, 0) == 0); + + s[0] = s[1] = '.'; + assert(charset_wctomb(charset, s, 0) == 1 && + s[0] == '\0' && s[1] == '.'); + assert(charset_wctomb(charset, s, 'x') == 1 && + s[0] == 'x' && s[1] == '.'); +} + +void test_utf8() +{ + struct charset *charset; + int wc; + char s[8]; + + charset = charset_find("UTF-8"); + test_any(charset); + + /* Decoder */ + wc = 0; + assert(charset_mbtowc(charset, &wc, "\177", 1) == 1 && wc == 127); + assert(charset_mbtowc(charset, &wc, "\200", 2) == -1); + assert(charset_mbtowc(charset, &wc, "\301\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\302\200", 1) == -1); + assert(charset_mbtowc(charset, &wc, "\302\200", 2) == 2 && wc == 128); + assert(charset_mbtowc(charset, &wc, "\302\200", 3) == 2 && wc == 128); + assert(charset_mbtowc(charset, &wc, "\340\237\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\340\240\200", 9) == 3 && + wc == 1 << 11); + assert(charset_mbtowc(charset, &wc, "\360\217\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\220\200\200", 9) == 4 && + wc == 1 << 16); + assert(charset_mbtowc(charset, &wc, "\370\207\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\370\210\200\200\200", 9) == 5 && + wc == 1 << 21); + assert(charset_mbtowc(charset, &wc, "\374\203\277\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\374\204\200\200\200\200", 9) == 6 && + wc == 1 << 26); + assert(charset_mbtowc(charset, &wc, "\375\277\277\277\277\277", 9) == 6 && + wc == 0x7fffffff); + + assert(charset_mbtowc(charset, &wc, "\302\000", 2) == -1); + assert(charset_mbtowc(charset, &wc, "\302\300", 2) == -1); + assert(charset_mbtowc(charset, &wc, "\340\040\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\340\340\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\340\240\000", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\340\240\300", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\020\200\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\320\200\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\220\000\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\220\300\200", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\220\200\000", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\360\220\200\300", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\077\277\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\377\277\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\277\077\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\277\377\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\277\277\277\077\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\277\277\277\377\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\277\277\277\277\077", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\375\277\277\277\277\377", 9) == -1); + + assert(charset_mbtowc(charset, &wc, "\376\277\277\277\277\277", 9) == -1); + assert(charset_mbtowc(charset, &wc, "\377\277\277\277\277\277", 9) == -1); + + /* Encoder */ + safe_strncpy(s, ".......", sizeof(s)); + assert(charset_wctomb(charset, s, 1 << 31) == -1 && + !strcmp(s, ".......")); + assert(charset_wctomb(charset, s, 127) == 1 && + !strcmp(s, "\177......")); + assert(charset_wctomb(charset, s, 128) == 2 && + !strcmp(s, "\302\200.....")); + assert(charset_wctomb(charset, s, 0x7ff) == 2 && + !strcmp(s, "\337\277.....")); + assert(charset_wctomb(charset, s, 0x800) == 3 && + !strcmp(s, "\340\240\200....")); + assert(charset_wctomb(charset, s, 0xffff) == 3 && + !strcmp(s, "\357\277\277....")); + assert(charset_wctomb(charset, s, 0x10000) == 4 && + !strcmp(s, "\360\220\200\200...")); + assert(charset_wctomb(charset, s, 0x1fffff) == 4 && + !strcmp(s, "\367\277\277\277...")); + assert(charset_wctomb(charset, s, 0x200000) == 5 && + !strcmp(s, "\370\210\200\200\200..")); + assert(charset_wctomb(charset, s, 0x3ffffff) == 5 && + !strcmp(s, "\373\277\277\277\277..")); + assert(charset_wctomb(charset, s, 0x4000000) == 6 && + !strcmp(s, "\374\204\200\200\200\200.")); + assert(charset_wctomb(charset, s, 0x7fffffff) == 6 && + !strcmp(s, "\375\277\277\277\277\277.")); +} + +void test_ascii() +{ + struct charset *charset; + int wc; + char s[3]; + + charset = charset_find("us-ascii"); + test_any(charset); + + /* Decoder */ + wc = 0; + assert(charset_mbtowc(charset, &wc, "\177", 2) == 1 && wc == 127); + assert(charset_mbtowc(charset, &wc, "\200", 2) == -1); + + /* Encoder */ + safe_strncpy(s, "..", sizeof(s)); + assert(charset_wctomb(charset, s, 256) == -1 && !strcmp(s, "..")); + assert(charset_wctomb(charset, s, 255) == -1); + assert(charset_wctomb(charset, s, 128) == -1); + assert(charset_wctomb(charset, s, 127) == 1 && !strcmp(s, "\177.")); +} + +void test_iso1() +{ + struct charset *charset; + int wc; + char s[3]; + + charset = charset_find("iso-8859-1"); + test_any(charset); + + /* Decoder */ + wc = 0; + assert(charset_mbtowc(charset, &wc, "\302\200", 9) == 1 && wc == 0xc2); + + /* Encoder */ + safe_strncpy(s, "..", sizeof(s)); + assert(charset_wctomb(charset, s, 256) == -1 && !strcmp(s, "..")); + assert(charset_wctomb(charset, s, 255) == 1 && !strcmp(s, "\377.")); + assert(charset_wctomb(charset, s, 128) == 1 && !strcmp(s, "\200.")); +} + +void test_iso2() +{ + struct charset *charset; + int wc; + char s[3]; + + charset = charset_find("iso-8859-2"); + test_any(charset); + + /* Decoder */ + wc = 0; + assert(charset_mbtowc(charset, &wc, "\302\200", 9) == 1 && wc == 0xc2); + assert(charset_mbtowc(charset, &wc, "\377", 2) == 1 && wc == 0x2d9); + + /* Encoder */ + safe_strncpy(s, "..", sizeof(s)); + assert(charset_wctomb(charset, s, 256) == -1 && !strcmp(s, "..")); + assert(charset_wctomb(charset, s, 255) == -1 && !strcmp(s, "..")); + assert(charset_wctomb(charset, s, 258) == 1 && !strcmp(s, "\303.")); + assert(charset_wctomb(charset, s, 128) == 1 && !strcmp(s, "\200.")); +} + +void test_convert() +{ + const char *p; + char *q, *r; + char s[256]; + size_t n, n2; + int i; + + p = "\000x\302\200\375\277\277\277\277\277"; + assert(charset_convert("UTF-8", "UTF-8", p, 10, &q, &n) == 0 && + n == 10 && !strcmp(p, q)); + assert(charset_convert("UTF-8", "UTF-8", "x\301\277y", 4, &q, &n) == 2 && + n == 4 && !strcmp(q, "x##y")); + assert(charset_convert("UTF-8", "UTF-8", "x\301\277y", 4, 0, &n) == 2 && + n == 4); + assert(charset_convert("UTF-8", "UTF-8", "x\301\277y", 4, &q, 0) == 2 && + !strcmp(q, "x##y")); + assert(charset_convert("UTF-8", "iso-8859-1", + "\302\200\304\200x", 5, &q, &n) == 1 && + n == 3 && !strcmp(q, "\200?x")); + assert(charset_convert("iso-8859-1", "UTF-8", + "\000\200\377", 3, &q, &n) == 0 && + n == 5 && !memcmp(q, "\000\302\200\303\277", 5)); + assert(charset_convert("iso-8859-1", "iso-8859-1", + "\000\200\377", 3, &q, &n) == 0 && + n == 3 && !memcmp(q, "\000\200\377", 3)); + + assert(charset_convert("iso-8859-2", "utf-8", "\300", 1, &q, &n) == 0 && + n == 2 && !strcmp(q, "\305\224")); + assert(charset_convert("utf-8", "iso-8859-2", "\305\224", 2, &q, &n) == 0 && + n == 1 && !strcmp(q, "\300")); + + for (i = 0; i < 256; i++) + s[i] = i; + + assert(charset_convert("iso-8859-2", "utf-8", s, 256, &q, &n) == 0); + assert(charset_convert("utf-8", "iso-8859-2", q, n, &r, &n2) == 0); + assert(n2 == 256 && !memcmp(r, s, n2)); +} + +int main() +{ + test_utf8(); + test_ascii(); + test_iso1(); + test_iso2(); + + test_convert(); + + return 0; +} diff --git a/deps/flac-1.3.2/src/share/utf8/iconvert.c b/deps/flac-1.3.2/src/share/utf8/iconvert.c new file mode 100644 index 0000000..472ca87 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/iconvert.c @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if !defined _WIN32 && defined HAVE_ICONV + +#include <assert.h> +#include <errno.h> +#include <iconv.h> +#include <stdlib.h> +#include <string.h> + +#include "iconvert.h" +#include "share/alloc.h" +#include "share/safe_str.h" + +/* + * Convert data from one encoding to another. Return: + * + * -2 : memory allocation failed + * -1 : unknown encoding + * 0 : data was converted exactly + * 1 : data was converted inexactly + * 2 : data was invalid (but still converted) + * + * We convert in two steps, via UTF-8, as this is the only + * reliable way of distinguishing between invalid input + * and valid input which iconv refuses to transliterate. + * We convert from UTF-8 twice, because we have no way of + * knowing whether the conversion was exact if iconv returns + * E2BIG (due to a bug in the specification of iconv). + * An alternative approach is to assume that the output of + * iconv is never more than 4 times as long as the input, + * but I prefer to avoid that assumption if possible. + */ + +int iconvert(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen) +{ + int ret = 0; + iconv_t cd1, cd2; + char *ib; + char *ob; + char *utfbuf = 0, *outbuf, *newbuf; + size_t utflen, outlen, ibl, obl, k; + char tbuf[2048]; + + cd1 = iconv_open("UTF-8", fromcode); + if (cd1 == (iconv_t)(-1)) + return -1; + + cd2 = (iconv_t)(-1); + /* Don't use strcasecmp() as it's locale-dependent. */ + if (!strchr("Uu", tocode[0]) || + !strchr("Tt", tocode[1]) || + !strchr("Ff", tocode[2]) || + tocode[3] != '-' || + tocode[4] != '8' || + tocode[5] != '\0') { + char *tocode1; + size_t dest_len = strlen(tocode) + 11; + /* + * Try using this non-standard feature of glibc and libiconv. + * This is deliberately not a config option as people often + * change their iconv library without rebuilding applications. + */ + tocode1 = safe_malloc_(dest_len); + if (!tocode1) + goto fail; + + safe_strncpy(tocode1, tocode, dest_len); + safe_strncat(tocode1, "//TRANSLIT", dest_len); + cd2 = iconv_open(tocode1, "UTF-8"); + free(tocode1); + + if (cd2 == (iconv_t)(-1)) + cd2 = iconv_open(tocode, fromcode); + + if (cd2 == (iconv_t)(-1)) { + iconv_close(cd1); + return -1; + } + } + + utflen = 1; /*fromlen * 2 + 1; XXX */ + utfbuf = malloc(utflen); + if (!utfbuf) + goto fail; + + /* Convert to UTF-8 */ + ib = (char *)from; + ibl = fromlen; + ob = utfbuf; + obl = utflen; + for (;;) { + k = iconv(cd1, &ib, &ibl, &ob, &obl); + assert((!k && !ibl) || + (k == (size_t)(-1) && errno == E2BIG && ibl && obl < 6) || + (k == (size_t)(-1) && + (errno == EILSEQ || errno == EINVAL) && ibl)); + if (!ibl) + break; + if (obl < 6) { + /* Enlarge the buffer */ + if(utflen*2 < utflen) /* overflow check */ + goto fail; + utflen *= 2; + newbuf = realloc(utfbuf, utflen); + if (!newbuf) + goto fail; + ob = (ob - utfbuf) + newbuf; + obl = utflen - (ob - newbuf); + utfbuf = newbuf; + } + else { + /* Invalid input */ + ib++, ibl--; + *ob++ = '#', obl--; + ret = 2; + iconv(cd1, 0, 0, 0, 0); + } + } + + if (cd2 == (iconv_t)(-1)) { + /* The target encoding was UTF-8 */ + if (tolen) + *tolen = ob - utfbuf; + if (!to) { + free(utfbuf); + iconv_close(cd1); + return ret; + } + newbuf = safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1); + if (!newbuf) + goto fail; + ob = (ob - utfbuf) + newbuf; + *ob = '\0'; + *to = newbuf; + iconv_close(cd1); + return ret; + } + + /* Truncate the buffer to be tidy */ + utflen = ob - utfbuf; + newbuf = realloc(utfbuf, utflen); + if (!newbuf) + goto fail; + utfbuf = newbuf; + + /* Convert from UTF-8 to discover how long the output is */ + outlen = 0; + ib = utfbuf; + ibl = utflen; + while (ibl) { + ob = tbuf; + obl = sizeof(tbuf); + k = iconv(cd2, &ib, &ibl, &ob, &obl); + assert((k != (size_t)(-1) && !ibl) || + (k == (size_t)(-1) && errno == E2BIG && ibl) || + (k == (size_t)(-1) && errno == EILSEQ && ibl)); + if (ibl && !(k == (size_t)(-1) && errno == E2BIG)) { + /* Replace one character */ + char *tb = "?"; + size_t tbl = 1; + + outlen += ob - tbuf; + ob = tbuf; + obl = sizeof(tbuf); + k = iconv(cd2, &tb, &tbl, &ob, &obl); + assert((!k && !tbl) || + (k == (size_t)(-1) && errno == EILSEQ && tbl)); + for (++ib, --ibl; ibl && (*ib & 0x80); ib++, ibl--) + ; + } + outlen += ob - tbuf; + } + ob = tbuf; + obl = sizeof(tbuf); + k = iconv(cd2, 0, 0, &ob, &obl); + assert(!k); + outlen += ob - tbuf; + + /* Convert from UTF-8 for real */ + outbuf = safe_malloc_add_2op_(outlen, /*+*/1); + if (!outbuf) + goto fail; + ib = utfbuf; + ibl = utflen; + ob = outbuf; + obl = outlen; + while (ibl) { + k = iconv(cd2, &ib, &ibl, &ob, &obl); + assert((k != (size_t)(-1) && !ibl) || + (k == (size_t)(-1) && errno == EILSEQ && ibl)); + if (k && !ret) + ret = 1; + if (ibl && !(k == (size_t)(-1) && errno == E2BIG)) { + /* Replace one character */ + char *tb = "?"; + size_t tbl = 1; + + k = iconv(cd2, &tb, &tbl, &ob, &obl); + assert((!k && !tbl) || + (k == (size_t)(-1) && errno == EILSEQ && tbl)); + for (++ib, --ibl; ibl && (*ib & 0x80); ib++, ibl--) + ; + } + } + k = iconv(cd2, 0, 0, &ob, &obl); + assert(!k); + assert(!obl); + *ob = '\0'; + + free(utfbuf); + iconv_close(cd1); + iconv_close(cd2); + if (tolen) + *tolen = outlen; + if (!to) { + free(outbuf); + return ret; + } + *to = outbuf; + return ret; + + fail: + if(0 != utfbuf) + free(utfbuf); + iconv_close(cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close(cd2); + return -2; +} + +#endif /* HAVE_ICONV */ diff --git a/deps/flac-1.3.2/src/share/utf8/iconvert.h b/deps/flac-1.3.2/src/share/utf8/iconvert.h new file mode 100644 index 0000000..a2d75a2 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/iconvert.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef HAVE_ICONV + +/* + * Convert data from one encoding to another. Return: + * + * -2 : memory allocation failed + * -1 : unknown encoding + * 0 : data was converted exactly + * 1 : data was converted inexactly + * 2 : data was invalid (but still converted) + * + * We convert in two steps, via UTF-8, as this is the only + * reliable way of distinguishing between invalid input + * and valid input which iconv refuses to transliterate. + * We convert from UTF-8 twice, because we have no way of + * knowing whether the conversion was exact if iconv returns + * E2BIG (due to a bug in the specification of iconv). + * An alternative approach is to assume that the output of + * iconv is never more than 4 times as long as the input, + * but I prefer to avoid that assumption if possible. + */ + +int iconvert(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen) ; + +#endif /* HAVE_ICONV */ diff --git a/deps/flac-1.3.2/src/share/utf8/makemap.c b/deps/flac-1.3.2/src/share/utf8/makemap.c new file mode 100644 index 0000000..59af608 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/makemap.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <iconv.h> +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + iconv_t cd; + const char *ib; + char *ob; + size_t ibl, obl, k; + unsigned char c, buf[4]; + int i, wc; + + if (argc != 2) { + printf("Usage: %s ENCODING\n", argv[0]); + printf("Output a charset map for the 8-bit ENCODING.\n"); + return 1; + } + + cd = iconv_open("UCS-4", argv[1]); + if (cd == (iconv_t)(-1)) { + perror("iconv_open"); + return 1; + } + + for (i = 0; i < 256; i++) { + c = i; + ib = &c; + ibl = 1; + ob = buf; + obl = 4; + k = iconv(cd, &ib, &ibl, &ob, &obl); + if (!k && !ibl && !obl) { + wc = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]; + if (wc >= 0xffff) { + printf("Dodgy value.\n"); + return 1; + } + } + else if (k == (size_t)(-1) && errno == EILSEQ) + wc = 0xffff; + else { + printf("Non-standard iconv.\n"); + return 1; + } + + if (i % 8 == 0) + printf(" "); + printf("0x%04x", wc); + if (i == 255) + printf("\n"); + else if (i % 8 == 7) + printf(",\n"); + else + printf(", "); + } + + return 0; +} diff --git a/deps/flac-1.3.2/src/share/utf8/utf8.c b/deps/flac-1.3.2/src/share/utf8/utf8.c new file mode 100644 index 0000000..0519d8e --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/utf8.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com> + * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> + * + * Buffer overflow checking added: Josh Coalson, 9/9/2007 + * + * Win32 part rewritten: lvqcl, 2/2/2016 + * + * 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 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * Convert a string between UTF-8 and the locale's charset. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> + +#include "share/alloc.h" +#include "share/utf8.h" + +#ifdef _WIN32 + +#include <windows.h> + +int utf8_encode(const char *from, char **to) +{ + wchar_t *unicode = NULL; + char *utf8 = NULL; + int ret = -1; + + do { + int len; + + len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, -1, NULL, 0); + if(len == 0) break; + + unicode = (wchar_t*) safe_malloc_mul_2op_((size_t)len, sizeof(wchar_t)); + if(unicode == NULL) break; + + len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, -1, unicode, len); + if(len == 0) break; + + len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL); + if(len == 0) break; + + utf8 = (char*) safe_malloc_mul_2op_((size_t)len, sizeof(char)); + if(utf8 == NULL) break; + + len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, len, NULL, NULL); + if(len == 0) break; + + ret = 0; + + } while(0); + + free(unicode); + + if(ret == 0) { + *to = utf8; + } else { + free(utf8); + *to = NULL; + } + + return ret; +} + +int utf8_decode(const char *from, char **to) +{ + wchar_t *unicode = NULL; + char *acp = NULL; + int ret = -1; + + do { + int len; + + len = MultiByteToWideChar(CP_UTF8, 0, from, -1, NULL, 0); + if(len == 0) break; + + unicode = (wchar_t*) safe_malloc_mul_2op_((size_t)len, sizeof(wchar_t)); + if(unicode == NULL) break; + + len = MultiByteToWideChar(CP_UTF8, 0, from, -1, unicode, len); + if(len == 0) break; + + len = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + if(len == 0) break; + + acp = (char*) safe_malloc_mul_2op_((size_t)len, sizeof(char)); + if(acp == NULL) break; + + len = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, acp, len, NULL, NULL); + if(len == 0) break; + + ret = 0; + + } while(0); + + free(unicode); + + if(ret == 0) { + *to = acp; + } else { + free(acp); + *to = NULL; + } + + return ret; +} + +#else /* End win32. Rest is for real operating systems */ + + +#ifdef HAVE_LANGINFO_CODESET +#include <langinfo.h> +#endif + +#include <string.h> + +#include "share/safe_str.h" +#include "iconvert.h" +#include "charset.h" + +static const char *current_charset(void) +{ + const char *c = 0; +#ifdef HAVE_LANGINFO_CODESET + c = nl_langinfo(CODESET); +#endif + + if (!c) + c = getenv("CHARSET"); + + return c? c : "US-ASCII"; +} + +static int convert_buffer(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen) +{ + int ret = -1; + +#ifdef HAVE_ICONV + ret = iconvert(fromcode, tocode, from, fromlen, to, tolen); + if (ret != -1) + return ret; +#endif + +#ifndef HAVE_ICONV /* should be ifdef USE_CHARSET_CONVERT */ + ret = charset_convert(fromcode, tocode, from, fromlen, to, tolen); + if (ret != -1) + return ret; +#endif + + return ret; +} + +static int convert_string(const char *fromcode, const char *tocode, + const char *from, char **to, char replace) +{ + int ret; + size_t fromlen; + char *s; + + fromlen = strlen(from); + ret = convert_buffer(fromcode, tocode, from, fromlen, to, 0); + if (ret == -2) + return -1; + if (ret != -1) + return ret; + + s = safe_malloc_add_2op_(fromlen, /*+*/1); + if (!s) + return -1; + safe_strncpy(s, from, fromlen + 1); + *to = s; + for (; *s; s++) + if (*s & ~0x7f) + *s = replace; + return 3; +} + +int utf8_encode(const char *from, char **to) +{ + return convert_string(current_charset(), "UTF-8", from, to, '#'); +} + +int utf8_decode(const char *from, char **to) +{ + return convert_string("UTF-8", current_charset(), from, to, '?'); +} + +#endif diff --git a/deps/flac-1.3.2/src/share/utf8/utf8_static.vcproj b/deps/flac-1.3.2/src/share/utf8/utf8_static.vcproj new file mode 100644 index 0000000..87b8ad5 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/utf8_static.vcproj @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="utf8_static"
+ ProjectGUID="{4cefbc92-c215-11db-8314-0800200c9a66}"
+ RootNamespace="utf8_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\..\include\share\utf8.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\utf8.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/share/utf8/utf8_static.vcxproj b/deps/flac-1.3.2/src/share/utf8/utf8_static.vcxproj new file mode 100644 index 0000000..5298e92 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/utf8_static.vcxproj @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbc92-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>utf8_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\utf8.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="utf8.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/utf8/utf8_static.vcxproj.filters b/deps/flac-1.3.2/src/share/utf8/utf8_static.vcxproj.filters new file mode 100644 index 0000000..dfbaa99 --- /dev/null +++ b/deps/flac-1.3.2/src/share/utf8/utf8_static.vcxproj.filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{c96e2c5d-a952-4c1d-b3d7-294a5b216154}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\utf8.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="utf8.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/win_utf8_io/Makefile.lite b/deps/flac-1.3.2/src/share/win_utf8_io/Makefile.lite new file mode 100644 index 0000000..1549266 --- /dev/null +++ b/deps/flac-1.3.2/src/share/win_utf8_io/Makefile.lite @@ -0,0 +1,21 @@ +# +# GNU makefile +# + +topdir = ../../.. + +ifeq ($(OS),Darwin) + EXPLICIT_LIBS = $(libdir)/libFLAC.a $(OGG_EXPLICIT_LIBS) -lm +else + LIBS = -lFLAC $(OGG_LIBS) -lm +endif + +LIB_NAME = libwin_utf8_io +INCLUDES = -I$(topdir)/include + +SRCS_C = \ + win_utf8_io.c + +include $(topdir)/build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io.c b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io.c new file mode 100644 index 0000000..c61d27f --- /dev/null +++ b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io.c @@ -0,0 +1,253 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2013-2016 Xiph.Org Foundation + * + * 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 the Xiph.org Foundation 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 FOUNDATION 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <windows.h> +#include "share/win_utf8_io.h" +#include "share/windows_unicode_filenames.h" + +#define UTF8_BUFFER_SIZE 32768 + +static int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va) +{ + int rc; + +#if defined _MSC_VER + if (size == 0) + return 1024; + rc = vsnprintf_s(str, size, _TRUNCATE, fmt, va); + if (rc < 0) + rc = size - 1; +#elif defined __MINGW32__ + rc = __mingw_vsnprintf(str, size, fmt, va); +#else + rc = vsnprintf(str, size, fmt, va); +#endif + + return rc; +} + +/* convert WCHAR stored Unicode string to UTF-8. Caller is responsible for freeing memory */ +static char *utf8_from_wchar(const wchar_t *wstr) +{ + char *utf8str; + int len; + + if (!wstr) + return NULL; + if ((len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL)) == 0) + return NULL; + if ((utf8str = (char *)malloc(len)) == NULL) + return NULL; + if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8str, len, NULL, NULL) == 0) { + free(utf8str); + utf8str = NULL; + } + + return utf8str; +} + +/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */ +static wchar_t *wchar_from_utf8(const char *str) +{ + wchar_t *widestr; + int len; + + if (!str) + return NULL; + if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0) + return NULL; + if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL) + return NULL; + if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) { + free(widestr); + widestr = NULL; + } + + return widestr; +} + +/* retrieve WCHAR commandline, expand wildcards and convert everything to UTF-8 */ +int get_utf8_argv(int *argc, char ***argv) +{ + typedef int (__cdecl *wgetmainargs_t)(int*, wchar_t***, wchar_t***, int, int*); + wgetmainargs_t wgetmainargs; + HMODULE handle; + int wargc; + wchar_t **wargv; + wchar_t **wenv; + char **utf8argv; + int ret, i; + + if ((handle = LoadLibrary("msvcrt.dll")) == NULL) return 1; + if ((wgetmainargs = (wgetmainargs_t)GetProcAddress(handle, "__wgetmainargs")) == NULL) { + FreeLibrary(handle); + return 1; + } + i = 0; + /* when the 4th argument is 1, __wgetmainargs expands wildcards but also erroneously converts \\?\c:\path\to\file.flac to \\file.flac */ + if (wgetmainargs(&wargc, &wargv, &wenv, 1, &i) != 0) { + FreeLibrary(handle); + return 1; + } + if ((utf8argv = (char **)calloc(wargc, sizeof(char*))) == NULL) { + FreeLibrary(handle); + return 1; + } + + ret = 0; + for (i=0; i<wargc; i++) { + if ((utf8argv[i] = utf8_from_wchar(wargv[i])) == NULL) { + ret = 1; + break; + } + } + + FreeLibrary(handle); /* do not free it when wargv or wenv are still in use */ + + if (ret == 0) { + flac_set_utf8_filenames(true); + *argc = wargc; + *argv = utf8argv; + } else { + for (i=0; i<wargc; i++) + free(utf8argv[i]); + free(utf8argv); + } + + return ret; +} + +/* return number of characters in the UTF-8 string */ +size_t strlen_utf8(const char *str) +{ + size_t len; + len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); /* includes terminating null */ + if (len != 0) + return len-1; + else + return strlen(str); +} + +/* get the console width in characters */ +int win_get_console_width(void) +{ + int width = 80; + CONSOLE_SCREEN_BUFFER_INFO csbi; + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if(hOut != INVALID_HANDLE_VALUE && hOut != NULL) + if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0) + width = csbi.dwSize.X; + return width; +} + +/* print functions */ + +static int wprint_console(FILE *stream, const wchar_t *text, size_t len) +{ + DWORD out; + int ret; + + do { + if (stream == stdout) { + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE || hOut == NULL || GetFileType(hOut) != FILE_TYPE_CHAR) + break; + if (WriteConsoleW(hOut, text, len, &out, NULL) == 0) + return -1; + return out; + } + if (stream == stderr) { + HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE); + if (hErr == INVALID_HANDLE_VALUE || hErr == NULL || GetFileType(hErr) != FILE_TYPE_CHAR) + break; + if (WriteConsoleW(hErr, text, len, &out, NULL) == 0) + return -1; + return out; + } + } while(0); + + ret = fputws(text, stream); + if (ret < 0) + return ret; + return len; +} + +int printf_utf8(const char *format, ...) +{ + int ret; + va_list argptr; + va_start(argptr, format); + + ret = vfprintf_utf8(stdout, format, argptr); + + va_end(argptr); + + return ret; +} + +int fprintf_utf8(FILE *stream, const char *format, ...) +{ + int ret; + va_list argptr; + va_start(argptr, format); + + ret = vfprintf_utf8(stream, format, argptr); + + va_end(argptr); + + return ret; +} + +int vfprintf_utf8(FILE *stream, const char *format, va_list argptr) +{ + char *utmp = NULL; + wchar_t *wout = NULL; + int ret = -1; + + do { + if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE))) break; + if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) <= 0) break; + if (!(wout = wchar_from_utf8(utmp))) { + ret = -1; + break; + } + ret = wprint_console(stream, wout, wcslen(wout)); + } while(0); + + free(utmp); + free(wout); + + return ret; +} diff --git a/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcproj b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcproj new file mode 100644 index 0000000..00eeea7 --- /dev/null +++ b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcproj @@ -0,0 +1,174 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="win_utf8_io_static"
+ ProjectGUID="{4cefbe02-c215-11db-8314-0800200c9a66}"
+ RootNamespace="win_utf8_io_static"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories=".\include;..\..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4267;4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Public Header Files"
+ >
+ <File
+ RelativePath="..\..\..\include\share\win_utf8_io.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\win_utf8_io.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcxproj b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcxproj new file mode 100644 index 0000000..aa9a3ee --- /dev/null +++ b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcxproj @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4cefbe02-c215-11db-8314-0800200c9a66}</ProjectGuid>
+ <RootNamespace>win_utf8_io_static</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\win_utf8_io.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="win_utf8_io.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcxproj.filters b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcxproj.filters new file mode 100644 index 0000000..e44a0c7 --- /dev/null +++ b/deps/flac-1.3.2/src/share/win_utf8_io/win_utf8_io_static.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Public Header Files">
+ <UniqueIdentifier>{6469e7f2-0837-4004-9f36-27d45ed62336}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\share\win_utf8_io.h">
+ <Filter>Public Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="win_utf8_io.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file |