parent
578c3737f8
commit
67caeb6e3c
@ -0,0 +1,5 @@ |
|||||||
|
Timothy B. Terriberry <tterribe@xiph.org> |
||||||
|
Ralph Giles <giles@xiph.org> |
||||||
|
Christopher "Monty" Montgomery <xiphmont@xiph.org> (original libvorbisfile) |
||||||
|
Gregory Maxwell <greg@xiph.org> (noise shaping dithering) |
||||||
|
nu774 <honeycomb77@gmail.com> (original winsock support) |
@ -0,0 +1,20 @@ |
|||||||
|
# Copyright 2023 jacqueline <me@jacqueline.id.au> |
||||||
|
# |
||||||
|
# SPDX-License-Identifier: GPL-3.0-only |
||||||
|
idf_component_register( |
||||||
|
SRCS src/info.c src/internal.c src/internal.h src/opusfile.c src/stream.c |
||||||
|
INCLUDE_DIRS "include" |
||||||
|
REQUIRES "ogg") |
||||||
|
target_compile_options("${COMPONENT_LIB}" PRIVATE "-DOP_FIXED_POINT") |
||||||
|
|
||||||
|
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) |
||||||
|
|
||||||
|
set(OPUS_FIXED_POINT ON) |
||||||
|
set(OPUS_ENABLE_FLOAT_API OFF) |
||||||
|
set(OPUS_INSTALL_PKG_CONFIG_MODULE OFF) |
||||||
|
set(OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF) |
||||||
|
set(OPUS_BUILD_TESTING OFF) |
||||||
|
set(OPUS_BUILD_SHARED_LIBS OFF) |
||||||
|
|
||||||
|
add_subdirectory($ENV{PROJ_PATH}/lib/opus ${CMAKE_CURRENT_BINARY_DIR}/opus) |
||||||
|
target_link_libraries(${COMPONENT_LIB} PUBLIC opus) |
@ -0,0 +1,28 @@ |
|||||||
|
Copyright (c) 1994-2013 Xiph.Org Foundation and contributors |
||||||
|
|
||||||
|
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. |
@ -0,0 +1,143 @@ |
|||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
AM_CFLAGS = -I$(top_srcdir)/include $(DEPS_CFLAGS)
|
||||||
|
|
||||||
|
dist_doc_DATA = COPYING AUTHORS README.md
|
||||||
|
|
||||||
|
opusincludedir = ${includedir}/opus
|
||||||
|
opusinclude_HEADERS = include/opusfile.h
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libopusfile.la libopusurl.la
|
||||||
|
libopusfile_la_SOURCES = \
|
||||||
|
src/info.c \
|
||||||
|
src/internal.c src/internal.h \
|
||||||
|
src/opusfile.c src/stream.c
|
||||||
|
libopusfile_la_LIBADD = $(DEPS_LIBS) $(lrintf_lib)
|
||||||
|
libopusfile_la_LDFLAGS = -no-undefined \
|
||||||
|
-version-info @OP_LT_CURRENT@:@OP_LT_REVISION@:@OP_LT_AGE@
|
||||||
|
|
||||||
|
libopusurl_la_SOURCES = src/http.c src/internal.c src/internal.h
|
||||||
|
libopusurl_la_CFLAGS = $(AM_CFLAGS) $(URL_DEPS_CFLAGS)
|
||||||
|
libopusurl_la_LIBADD = libopusfile.la $(URL_DEPS_LIBS)
|
||||||
|
libopusurl_la_LDFLAGS = -no-undefined \
|
||||||
|
-version-info @OP_LT_CURRENT@:@OP_LT_REVISION@:@OP_LT_AGE@
|
||||||
|
|
||||||
|
if OP_ENABLE_EXAMPLES |
||||||
|
noinst_PROGRAMS = examples/opusfile_example examples/seeking_example
|
||||||
|
endif |
||||||
|
|
||||||
|
examples_opusfile_example_SOURCES = examples/opusfile_example.c
|
||||||
|
examples_seeking_example_SOURCES = examples/seeking_example.c
|
||||||
|
examples_opusfile_example_LDADD = libopusurl.la libopusfile.la
|
||||||
|
examples_seeking_example_LDADD = libopusurl.la libopusfile.la
|
||||||
|
|
||||||
|
if OP_WIN32 |
||||||
|
if OP_ENABLE_HTTP |
||||||
|
libopusurl_la_SOURCES += src/wincerts.c src/winerrno.h
|
||||||
|
libopusurl_la_LIBADD += -lws2_32 -lcrypt32
|
||||||
|
endif |
||||||
|
examples_opusfile_example_SOURCES += examples/win32utf8.c examples/win32utf8.h
|
||||||
|
examples_seeking_example_SOURCES += examples/win32utf8.c examples/win32utf8.h
|
||||||
|
endif |
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = opusfile.pc opusurl.pc
|
||||||
|
|
||||||
|
debug: |
||||||
|
$(MAKE) CFLAGS="${CFLAGS} -O0 -ggdb -DOP_ENABLE_ASSERTIONS" all
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
opusfile.pc.in \
|
||||||
|
opusurl.pc.in \
|
||||||
|
opusfile-uninstalled.pc.in \
|
||||||
|
opusurl-uninstalled.pc.in \
|
||||||
|
doc/Doxyfile.in \
|
||||||
|
doc/opus_logo.svg \
|
||||||
|
doc/Makefile \
|
||||||
|
unix/Makefile \
|
||||||
|
win32/VS2015/opusfile.sln \
|
||||||
|
win32/VS2015/opusfile.vcxproj \
|
||||||
|
win32/VS2015/opusfile.vcxproj.filters \
|
||||||
|
win32/VS2015/opusfile_example.vcxproj \
|
||||||
|
win32/VS2015/opusfile_example.vcxproj.filters \
|
||||||
|
win32/VS2015/seeking_example.vcxproj \
|
||||||
|
win32/VS2015/seeking_example.vcxproj.filters
|
||||||
|
|
||||||
|
# Targets to build and install just the library without the docs
|
||||||
|
opusfile install-opusfile: NO_DOXYGEN = 1 |
||||||
|
|
||||||
|
opusfile: all |
||||||
|
install-opusfile: install |
||||||
|
|
||||||
|
# Or just the docs
|
||||||
|
docs: doc/doxygen-build.stamp |
||||||
|
|
||||||
|
install-docs: |
||||||
|
@if [ -z "$(NO_DOXYGEN)" ]; then \
|
||||||
|
( cd doc && \
|
||||||
|
echo "Installing documentation in $(DESTDIR)$(docdir)"; \
|
||||||
|
$(INSTALL) -d $(DESTDIR)$(docdir)/html/search; \
|
||||||
|
for f in `find html -type f \! -name "installdox"` ; do \
|
||||||
|
$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \
|
||||||
|
done ) \
|
||||||
|
fi
|
||||||
|
|
||||||
|
doc/doxygen-build.stamp: doc/Doxyfile $(top_srcdir)/doc/opus_logo.svg \
|
||||||
|
$(top_srcdir)/include/*.h
|
||||||
|
@[ -n "$(NO_DOXYGEN)" ] || ( cd doc && doxygen && touch $(@F) )
|
||||||
|
|
||||||
|
|
||||||
|
if HAVE_DOXYGEN |
||||||
|
|
||||||
|
# Or everything (by default)
|
||||||
|
all-local: docs |
||||||
|
|
||||||
|
install-data-local: install-docs |
||||||
|
|
||||||
|
clean-local: |
||||||
|
$(RM) -r doc/html
|
||||||
|
$(RM) -r doc/latex
|
||||||
|
$(RM) doc/doxygen-build.stamp
|
||||||
|
|
||||||
|
uninstall-local: |
||||||
|
$(RM) -r $(DESTDIR)$(docdir)/html
|
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
# We check this every time make is run, with configure.ac being touched to
|
||||||
|
# trigger an update of the build system files if update_version changes the
|
||||||
|
# current PACKAGE_VERSION (or if package_version was modified manually by a
|
||||||
|
# user with either AUTO_UPDATE=no or no update_version script present - the
|
||||||
|
# latter being the normal case for tarball releases).
|
||||||
|
#
|
||||||
|
# We can't just add the package_version file to CONFIGURE_DEPENDENCIES since
|
||||||
|
# simply running autoconf will not actually regenerate configure for us when
|
||||||
|
# the content of that file changes (due to autoconf dependency checking not
|
||||||
|
# knowing about that without us creating yet another file for it to include).
|
||||||
|
#
|
||||||
|
# The MAKECMDGOALS check is a gnu-make'ism, but will degrade 'gracefully' for
|
||||||
|
# makes that don't support it. The only loss of functionality is not forcing
|
||||||
|
# an update of package_version for `make dist` if AUTO_UPDATE=no, but that is
|
||||||
|
# unlikely to be a real problem for any real user.
|
||||||
|
$(top_srcdir)/configure.ac: force |
||||||
|
@case "$(MAKECMDGOALS)" in \
|
||||||
|
dist-hook) exit 0 ;; \
|
||||||
|
dist-* | dist | distcheck | distclean) _arg=release ;; \
|
||||||
|
esac; \
|
||||||
|
if ! $(top_srcdir)/update_version $$_arg 2> /dev/null; then \
|
||||||
|
if [ ! -e $(top_srcdir)/package_version ]; then \
|
||||||
|
echo 'PACKAGE_VERSION="unknown"' > $(top_srcdir)/package_version; \
|
||||||
|
fi; \
|
||||||
|
. $(top_srcdir)/package_version || exit 1; \
|
||||||
|
[ "$(PACKAGE_VERSION)" != "$$PACKAGE_VERSION" ] || exit 0; \
|
||||||
|
fi; \
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
force: |
||||||
|
|
||||||
|
# Create a minimal package_version file when make dist is run.
|
||||||
|
dist-hook: |
||||||
|
echo 'PACKAGE_VERSION="$(PACKAGE_VERSION)"' > $(top_distdir)/package_version
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: opusfile install-opusfile docs install-docs |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@ |
|||||||
|
# Opusfile |
||||||
|
|
||||||
|
[](https://gitlab.xiph.org/xiph/opusfile/commits/master) |
||||||
|
[](https://travis-ci.org/xiph/opusfile) |
||||||
|
[](https://ci.appveyor.com/project/rillian/opusfile) |
||||||
|
|
||||||
|
The opusfile and opusurl libraries provide a high-level API for |
||||||
|
decoding and seeking within .opus files on disk or over http(s). |
||||||
|
|
||||||
|
opusfile depends on libopus and libogg. |
||||||
|
opusurl depends on opusfile and openssl. |
||||||
|
|
||||||
|
The library is functional, but there are likely issues |
||||||
|
we didn't find in our own testing. Please give feedback |
||||||
|
in #opus on irc.freenode.net or at opus@xiph.org. |
||||||
|
|
||||||
|
Programming documentation is available in tree and online at |
||||||
|
https://opus-codec.org/docs/ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,348 @@ |
|||||||
|
#! /bin/sh |
||||||
|
# Wrapper for compilers which do not understand '-c -o'. |
||||||
|
|
||||||
|
scriptversion=2018-03-07.03; # UTC |
||||||
|
|
||||||
|
# Copyright (C) 1999-2020 Free Software Foundation, Inc. |
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>. |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2, or (at your option) |
||||||
|
# any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you |
||||||
|
# distribute this file as part of a program that contains a |
||||||
|
# configuration script generated by Autoconf, you may include it under |
||||||
|
# the same distribution terms that you use for the rest of that program. |
||||||
|
|
||||||
|
# This file is maintained in Automake, please report |
||||||
|
# bugs to <bug-automake@gnu.org> or send patches to |
||||||
|
# <automake-patches@gnu.org>. |
||||||
|
|
||||||
|
nl=' |
||||||
|
' |
||||||
|
|
||||||
|
# We need space, tab and new line, in precisely that order. Quoting is |
||||||
|
# there to prevent tools from complaining about whitespace usage. |
||||||
|
IFS=" "" $nl" |
||||||
|
|
||||||
|
file_conv= |
||||||
|
|
||||||
|
# func_file_conv build_file lazy |
||||||
|
# Convert a $build file to $host form and store it in $file |
||||||
|
# Currently only supports Windows hosts. If the determined conversion |
||||||
|
# type is listed in (the comma separated) LAZY, no conversion will |
||||||
|
# take place. |
||||||
|
func_file_conv () |
||||||
|
{ |
||||||
|
file=$1 |
||||||
|
case $file in |
||||||
|
/ | /[!/]*) # absolute file, and not a UNC file |
||||||
|
if test -z "$file_conv"; then |
||||||
|
# lazily determine how to convert abs files |
||||||
|
case `uname -s` in |
||||||
|
MINGW*) |
||||||
|
file_conv=mingw |
||||||
|
;; |
||||||
|
CYGWIN* | MSYS*) |
||||||
|
file_conv=cygwin |
||||||
|
;; |
||||||
|
*) |
||||||
|
file_conv=wine |
||||||
|
;; |
||||||
|
esac |
||||||
|
fi |
||||||
|
case $file_conv/,$2, in |
||||||
|
*,$file_conv,*) |
||||||
|
;; |
||||||
|
mingw/*) |
||||||
|
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` |
||||||
|
;; |
||||||
|
cygwin/* | msys/*) |
||||||
|
file=`cygpath -m "$file" || echo "$file"` |
||||||
|
;; |
||||||
|
wine/*) |
||||||
|
file=`winepath -w "$file" || echo "$file"` |
||||||
|
;; |
||||||
|
esac |
||||||
|
;; |
||||||
|
esac |
||||||
|
} |
||||||
|
|
||||||
|
# func_cl_dashL linkdir |
||||||
|
# Make cl look for libraries in LINKDIR |
||||||
|
func_cl_dashL () |
||||||
|
{ |
||||||
|
func_file_conv "$1" |
||||||
|
if test -z "$lib_path"; then |
||||||
|
lib_path=$file |
||||||
|
else |
||||||
|
lib_path="$lib_path;$file" |
||||||
|
fi |
||||||
|
linker_opts="$linker_opts -LIBPATH:$file" |
||||||
|
} |
||||||
|
|
||||||
|
# func_cl_dashl library |
||||||
|
# Do a library search-path lookup for cl |
||||||
|
func_cl_dashl () |
||||||
|
{ |
||||||
|
lib=$1 |
||||||
|
found=no |
||||||
|
save_IFS=$IFS |
||||||
|
IFS=';' |
||||||
|
for dir in $lib_path $LIB |
||||||
|
do |
||||||
|
IFS=$save_IFS |
||||||
|
if $shared && test -f "$dir/$lib.dll.lib"; then |
||||||
|
found=yes |
||||||
|
lib=$dir/$lib.dll.lib |
||||||
|
break |
||||||
|
fi |
||||||
|
if test -f "$dir/$lib.lib"; then |
||||||
|
found=yes |
||||||
|
lib=$dir/$lib.lib |
||||||
|
break |
||||||
|
fi |
||||||
|
if test -f "$dir/lib$lib.a"; then |
||||||
|
found=yes |
||||||
|
lib=$dir/lib$lib.a |
||||||
|
break |
||||||
|
fi |
||||||
|
done |
||||||
|
IFS=$save_IFS |
||||||
|
|
||||||
|
if test "$found" != yes; then |
||||||
|
lib=$lib.lib |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# func_cl_wrapper cl arg... |
||||||
|
# Adjust compile command to suit cl |
||||||
|
func_cl_wrapper () |
||||||
|
{ |
||||||
|
# Assume a capable shell |
||||||
|
lib_path= |
||||||
|
shared=: |
||||||
|
linker_opts= |
||||||
|
for arg |
||||||
|
do |
||||||
|
if test -n "$eat"; then |
||||||
|
eat= |
||||||
|
else |
||||||
|
case $1 in |
||||||
|
-o) |
||||||
|
# configure might choose to run compile as 'compile cc -o foo foo.c'. |
||||||
|
eat=1 |
||||||
|
case $2 in |
||||||
|
*.o | *.[oO][bB][jJ]) |
||||||
|
func_file_conv "$2" |
||||||
|
set x "$@" -Fo"$file" |
||||||
|
shift |
||||||
|
;; |
||||||
|
*) |
||||||
|
func_file_conv "$2" |
||||||
|
set x "$@" -Fe"$file" |
||||||
|
shift |
||||||
|
;; |
||||||
|
esac |
||||||
|
;; |
||||||
|
-I) |
||||||
|
eat=1 |
||||||
|
func_file_conv "$2" mingw |
||||||
|
set x "$@" -I"$file" |
||||||
|
shift |
||||||
|
;; |
||||||
|
-I*) |
||||||
|
func_file_conv "${1#-I}" mingw |
||||||
|
set x "$@" -I"$file" |
||||||
|
shift |
||||||
|
;; |
||||||
|
-l) |
||||||
|
eat=1 |
||||||
|
func_cl_dashl "$2" |
||||||
|
set x "$@" "$lib" |
||||||
|
shift |
||||||
|
;; |
||||||
|
-l*) |
||||||
|
func_cl_dashl "${1#-l}" |
||||||
|
set x "$@" "$lib" |
||||||
|
shift |
||||||
|
;; |
||||||
|
-L) |
||||||
|
eat=1 |
||||||
|
func_cl_dashL "$2" |
||||||
|
;; |
||||||
|
-L*) |
||||||
|
func_cl_dashL "${1#-L}" |
||||||
|
;; |
||||||
|
-static) |
||||||
|
shared=false |
||||||
|
;; |
||||||
|
-Wl,*) |
||||||
|
arg=${1#-Wl,} |
||||||
|
save_ifs="$IFS"; IFS=',' |
||||||
|
for flag in $arg; do |
||||||
|
IFS="$save_ifs" |
||||||
|
linker_opts="$linker_opts $flag" |
||||||
|
done |
||||||
|
IFS="$save_ifs" |
||||||
|
;; |
||||||
|
-Xlinker) |
||||||
|
eat=1 |
||||||
|
linker_opts="$linker_opts $2" |
||||||
|
;; |
||||||
|
-*) |
||||||
|
set x "$@" "$1" |
||||||
|
shift |
||||||
|
;; |
||||||
|
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++) |
||||||
|
func_file_conv "$1" |
||||||
|
set x "$@" -Tp"$file" |
||||||
|
shift |
||||||
|
;; |
||||||
|
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) |
||||||
|
func_file_conv "$1" mingw |
||||||
|
set x "$@" "$file" |
||||||
|
shift |
||||||
|
;; |
||||||
|
*) |
||||||
|
set x "$@" "$1" |
||||||
|
shift |
||||||
|
;; |
||||||
|
esac |
||||||
|
fi |
||||||
|
shift |
||||||
|
done |
||||||
|
if test -n "$linker_opts"; then |
||||||
|
linker_opts="-link$linker_opts" |
||||||
|
fi |
||||||
|
exec "$@" $linker_opts |
||||||
|
exit 1 |
||||||
|
} |
||||||
|
|
||||||
|
eat= |
||||||
|
|
||||||
|
case $1 in |
||||||
|
'') |
||||||
|
echo "$0: No command. Try '$0 --help' for more information." 1>&2 |
||||||
|
exit 1; |
||||||
|
;; |
||||||
|
-h | --h*) |
||||||
|
cat <<\EOF |
||||||
|
Usage: compile [--help] [--version] PROGRAM [ARGS] |
||||||
|
|
||||||
|
Wrapper for compilers which do not understand '-c -o'. |
||||||
|
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining |
||||||
|
arguments, and rename the output as expected. |
||||||
|
|
||||||
|
If you are trying to build a whole package this is not the |
||||||
|
right script to run: please start by reading the file 'INSTALL'. |
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>. |
||||||
|
EOF |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
-v | --v*) |
||||||
|
echo "compile $scriptversion" |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ |
||||||
|
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) |
||||||
|
func_cl_wrapper "$@" # Doesn't return... |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
ofile= |
||||||
|
cfile= |
||||||
|
|
||||||
|
for arg |
||||||
|
do |
||||||
|
if test -n "$eat"; then |
||||||
|
eat= |
||||||
|
else |
||||||
|
case $1 in |
||||||
|
-o) |
||||||
|
# configure might choose to run compile as 'compile cc -o foo foo.c'. |
||||||
|
# So we strip '-o arg' only if arg is an object. |
||||||
|
eat=1 |
||||||
|
case $2 in |
||||||
|
*.o | *.obj) |
||||||
|
ofile=$2 |
||||||
|
;; |
||||||
|
*) |
||||||
|
set x "$@" -o "$2" |
||||||
|
shift |
||||||
|
;; |
||||||
|
esac |
||||||
|
;; |
||||||
|
*.c) |
||||||
|
cfile=$1 |
||||||
|
set x "$@" "$1" |
||||||
|
shift |
||||||
|
;; |
||||||
|
*) |
||||||
|
set x "$@" "$1" |
||||||
|
shift |
||||||
|
;; |
||||||
|
esac |
||||||
|
fi |
||||||
|
shift |
||||||
|
done |
||||||
|
|
||||||
|
if test -z "$ofile" || test -z "$cfile"; then |
||||||
|
# If no '-o' option was seen then we might have been invoked from a |
||||||
|
# pattern rule where we don't need one. That is ok -- this is a |
||||||
|
# normal compilation that the losing compiler can handle. If no |
||||||
|
# '.c' file was seen then we are probably linking. That is also |
||||||
|
# ok. |
||||||
|
exec "$@" |
||||||
|
fi |
||||||
|
|
||||||
|
# Name of file we expect compiler to create. |
||||||
|
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` |
||||||
|
|
||||||
|
# Create the lock directory. |
||||||
|
# Note: use '[/\\:.-]' here to ensure that we don't use the same name |
||||||
|
# that we are using for the .o file. Also, base the name on the expected |
||||||
|
# object file name, since that is what matters with a parallel build. |
||||||
|
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d |
||||||
|
while true; do |
||||||
|
if mkdir "$lockdir" >/dev/null 2>&1; then |
||||||
|
break |
||||||
|
fi |
||||||
|
sleep 1 |
||||||
|
done |
||||||
|
# FIXME: race condition here if user kills between mkdir and trap. |
||||||
|
trap "rmdir '$lockdir'; exit 1" 1 2 15 |
||||||
|
|
||||||
|
# Run the compile. |
||||||
|
"$@" |
||||||
|
ret=$? |
||||||
|
|
||||||
|
if test -f "$cofile"; then |
||||||
|
test "$cofile" = "$ofile" || mv "$cofile" "$ofile" |
||||||
|
elif test -f "${cofile}bj"; then |
||||||
|
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" |
||||||
|
fi |
||||||
|
|
||||||
|
rmdir "$lockdir" |
||||||
|
exit $ret |
||||||
|
|
||||||
|
# Local Variables: |
||||||
|
# mode: shell-script |
||||||
|
# sh-indentation: 2 |
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp) |
||||||
|
# time-stamp-start: "scriptversion=" |
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H" |
||||||
|
# time-stamp-time-zone: "UTC0" |
||||||
|
# time-stamp-end: "; # UTC" |
||||||
|
# End: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,127 @@ |
|||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */ |
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */ |
||||||
|
#undef HAVE_DLFCN_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */ |
||||||
|
#undef HAVE_INTTYPES_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */ |
||||||
|
#undef HAVE_MEMORY_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */ |
||||||
|
#undef HAVE_STDINT_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */ |
||||||
|
#undef HAVE_STDLIB_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */ |
||||||
|
#undef HAVE_STRINGS_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */ |
||||||
|
#undef HAVE_STRING_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */ |
||||||
|
#undef HAVE_SYS_STAT_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */ |
||||||
|
#undef HAVE_SYS_TYPES_H |
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */ |
||||||
|
#undef HAVE_UNISTD_H |
||||||
|
|
||||||
|
/* Define to the sub-directory where libtool stores uninstalled libraries. */ |
||||||
|
#undef LT_OBJDIR |
||||||
|
|
||||||
|
/* Disable floating-point API */ |
||||||
|
#undef OP_DISABLE_FLOAT_API |
||||||
|
|
||||||
|
/* Enable assertions in code */ |
||||||
|
#undef OP_ENABLE_ASSERTIONS |
||||||
|
|
||||||
|
/* Enable HTTP support */ |
||||||
|
#undef OP_ENABLE_HTTP |
||||||
|
|
||||||
|
/* Enable fixed-point calculation */ |
||||||
|
#undef OP_FIXED_POINT |
||||||
|
|
||||||
|
/* Enable use of clock_gettime function */ |
||||||
|
#undef OP_HAVE_CLOCK_GETTIME |
||||||
|
|
||||||
|
/* Enable use of lrintf function */ |
||||||
|
#undef OP_HAVE_LRINTF |
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */ |
||||||
|
#undef PACKAGE_BUGREPORT |
||||||
|
|
||||||
|
/* Define to the full name of this package. */ |
||||||
|
#undef PACKAGE_NAME |
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */ |
||||||
|
#undef PACKAGE_STRING |
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */ |
||||||
|
#undef PACKAGE_TARNAME |
||||||
|
|
||||||
|
/* Define to the home page for this package. */ |
||||||
|
#undef PACKAGE_URL |
||||||
|
|
||||||
|
/* Define to the version of this package. */ |
||||||
|
#undef PACKAGE_VERSION |
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */ |
||||||
|
#undef STDC_HEADERS |
||||||
|
|
||||||
|
/* Define this if the compiler supports __attribute__((
|
||||||
|
ifelse([visibility("default")], , [visibility_default], |
||||||
|
[visibility("default")]) )) */ |
||||||
|
#undef SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT |
||||||
|
|
||||||
|
/* Define this if the compiler supports the -fvisibility flag */ |
||||||
|
#undef SUPPORT_FLAG_VISIBILITY |
||||||
|
|
||||||
|
/* Enable extensions on AIX 3, Interix. */ |
||||||
|
#ifndef _ALL_SOURCE |
||||||
|
# undef _ALL_SOURCE |
||||||
|
#endif |
||||||
|
/* Enable GNU extensions on systems that have them. */ |
||||||
|
#ifndef _GNU_SOURCE |
||||||
|
# undef _GNU_SOURCE |
||||||
|
#endif |
||||||
|
/* Enable threading extensions on Solaris. */ |
||||||
|
#ifndef _POSIX_PTHREAD_SEMANTICS |
||||||
|
# undef _POSIX_PTHREAD_SEMANTICS |
||||||
|
#endif |
||||||
|
/* Enable extensions on HP NonStop. */ |
||||||
|
#ifndef _TANDEM_SOURCE |
||||||
|
# undef _TANDEM_SOURCE |
||||||
|
#endif |
||||||
|
/* Enable general extensions on Solaris. */ |
||||||
|
#ifndef __EXTENSIONS__ |
||||||
|
# undef __EXTENSIONS__ |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
/* Enable large inode numbers on Mac OS X 10.5. */ |
||||||
|
#ifndef _DARWIN_USE_64_BIT_INODE |
||||||
|
# define _DARWIN_USE_64_BIT_INODE 1 |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Number of bits in a file offset, on hosts where this is settable. */ |
||||||
|
#undef _FILE_OFFSET_BITS |
||||||
|
|
||||||
|
/* Define for large files, on AIX-style hosts. */ |
||||||
|
#undef _LARGE_FILES |
||||||
|
|
||||||
|
/* Define to 1 if on MINIX. */ |
||||||
|
#undef _MINIX |
||||||
|
|
||||||
|
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||||
|
this defined. */ |
||||||
|
#undef _POSIX_1_SOURCE |
||||||
|
|
||||||
|
/* Define to 1 if you need to in order for `stat' and other things to work. */ |
||||||
|
#undef _POSIX_SOURCE |
||||||
|
|
||||||
|
/* We need at least WindowsXP for getaddrinfo/freeaddrinfo */ |
||||||
|
#undef _WIN32_WINNT |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,210 @@ |
|||||||
|
# autoconf source script for generating configure |
||||||
|
|
||||||
|
dnl The package_version file will be automatically synced to the git revision |
||||||
|
dnl by the update_version script when configured in the repository, but will |
||||||
|
dnl remain constant in tarball releases unless it is manually edited. |
||||||
|
m4_define([CURRENT_VERSION], |
||||||
|
m4_esyscmd([ ./update_version 2>/dev/null || true |
||||||
|
if test -e package_version; then |
||||||
|
. ./package_version |
||||||
|
printf "$PACKAGE_VERSION" |
||||||
|
else |
||||||
|
printf "unknown" |
||||||
|
fi ])) |
||||||
|
|
||||||
|
AC_INIT([opusfile],[CURRENT_VERSION],[opus@xiph.org]) |
||||||
|
AC_CONFIG_SRCDIR([src/opusfile.c]) |
||||||
|
AC_CONFIG_MACRO_DIR([m4]) |
||||||
|
|
||||||
|
AC_USE_SYSTEM_EXTENSIONS |
||||||
|
AC_SYS_LARGEFILE |
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([1.11 foreign no-define dist-zip subdir-objects]) |
||||||
|
AM_MAINTAINER_MODE([enable]) |
||||||
|
LT_INIT |
||||||
|
|
||||||
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) |
||||||
|
|
||||||
|
dnl Library versioning for libtool. |
||||||
|
dnl Please update these for releases. |
||||||
|
dnl CURRENT, REVISION, AGE |
||||||
|
dnl - library source changed -> increment REVISION |
||||||
|
dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 |
||||||
|
dnl - interfaces added -> increment AGE |
||||||
|
dnl - interfaces removed -> AGE = 0 |
||||||
|
|
||||||
|
OP_LT_CURRENT=4 |
||||||
|
OP_LT_REVISION=5 |
||||||
|
OP_LT_AGE=4 |
||||||
|
|
||||||
|
AC_SUBST(OP_LT_CURRENT) |
||||||
|
AC_SUBST(OP_LT_REVISION) |
||||||
|
AC_SUBST(OP_LT_AGE) |
||||||
|
|
||||||
|
CC_CHECK_CFLAGS_APPEND( |
||||||
|
[-std=c89 -pedantic -Wall -Wextra -Wno-parentheses -Wno-long-long]) |
||||||
|
|
||||||
|
# Platform-specific tweaks |
||||||
|
case $host in |
||||||
|
*-mingw*) |
||||||
|
# -std=c89 causes some warnings under mingw. |
||||||
|
CC_CHECK_CFLAGS_APPEND([-U__STRICT_ANSI__]) |
||||||
|
# We need WINNT>=0x501 (WindowsXP) for getaddrinfo/freeaddrinfo. |
||||||
|
# It's okay to define this even when HTTP support is disabled, as it only |
||||||
|
# affects header declarations, not linking (unless we actually use some |
||||||
|
# XP-only functions). |
||||||
|
AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x501, |
||||||
|
[We need at least WindowsXP for getaddrinfo/freeaddrinfo]) |
||||||
|
host_mingw=true |
||||||
|
;; |
||||||
|
esac |
||||||
|
AM_CONDITIONAL(OP_WIN32, [test "$host_mingw" = "true"]) |
||||||
|
|
||||||
|
AC_ARG_ENABLE([assertions], |
||||||
|
AS_HELP_STRING([--enable-assertions], [Enable assertions in code]),, |
||||||
|
enable_assertions=no) |
||||||
|
|
||||||
|
AS_IF([test "$enable_assertions" = "yes"], [ |
||||||
|
AC_DEFINE([OP_ENABLE_ASSERTIONS], [1], [Enable assertions in code]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_ARG_ENABLE([http], |
||||||
|
AS_HELP_STRING([--disable-http], [Disable HTTP support]),, |
||||||
|
enable_http=yes) |
||||||
|
|
||||||
|
AM_COND_IF(OP_WIN32, [ |
||||||
|
AS_IF([test "$enable_http" != "no"], [ |
||||||
|
AC_CHECK_HEADER([winsock2.h],, [ |
||||||
|
AC_MSG_WARN([HTTP support requires a Winsock socket library.]) |
||||||
|
enable_http=no |
||||||
|
]) |
||||||
|
]) |
||||||
|
], [ |
||||||
|
AS_IF([test "$enable_http" != "no"], [ |
||||||
|
AC_CHECK_HEADER([sys/socket.h],, [ |
||||||
|
AC_MSG_WARN([HTTP support requires a POSIX socket library.]) |
||||||
|
enable_http=no |
||||||
|
]) |
||||||
|
]) |
||||||
|
]) |
||||||
|
|
||||||
|
# HTTP support requires either clock_gettime or ftime. clock_gettime is |
||||||
|
# used only if time.h defines CLOCK_REALTIME and the function is available |
||||||
|
# in the standard library; on platforms such as glibc < 2.17 where -lrt |
||||||
|
# or another library would be required, ftime will be used. |
||||||
|
AS_IF([test "$enable_http" != "no"], [ |
||||||
|
AC_MSG_CHECKING([for clock_gettime]) |
||||||
|
AC_LINK_IFELSE([ |
||||||
|
AC_LANG_PROGRAM([[#include <time.h>]], [[ |
||||||
|
struct timespec ts; |
||||||
|
return clock_gettime(CLOCK_REALTIME, &ts); |
||||||
|
]]) |
||||||
|
], [ |
||||||
|
AC_MSG_RESULT([yes]) |
||||||
|
AC_DEFINE([OP_HAVE_CLOCK_GETTIME], [1], |
||||||
|
[Enable use of clock_gettime function]) |
||||||
|
], [ |
||||||
|
AC_MSG_RESULT([no]) |
||||||
|
AC_SEARCH_LIBS(ftime, [compat], , [enable_http=no]) |
||||||
|
]) |
||||||
|
]) |
||||||
|
|
||||||
|
m4_ifndef([PKG_PROG_PKG_CONFIG], |
||||||
|
[m4_fatal([Could not locate the pkg-config autoconf macros. |
||||||
|
Please make sure pkg-config is installed and, if necessary, set the environment |
||||||
|
variable ACLOCAL="aclocal -I/path/to/pkg.m4".])]) |
||||||
|
|
||||||
|
AS_IF([test "$enable_http" != "no"], [ |
||||||
|
openssl="openssl" |
||||||
|
AC_DEFINE([OP_ENABLE_HTTP], [1], [Enable HTTP support]) |
||||||
|
PKG_CHECK_MODULES([URL_DEPS], [openssl]) |
||||||
|
]) |
||||||
|
AM_CONDITIONAL(OP_ENABLE_HTTP, [test "$enable_http" != "no"]) |
||||||
|
AC_SUBST([openssl]) |
||||||
|
|
||||||
|
PKG_CHECK_MODULES([DEPS], [ogg >= 1.3 opus >= 1.0.1]) |
||||||
|
|
||||||
|
AC_ARG_ENABLE([fixed-point], |
||||||
|
AS_HELP_STRING([--enable-fixed-point], [Enable fixed-point calculation]),, |
||||||
|
enable_fixed_point=no) |
||||||
|
AC_ARG_ENABLE([float], |
||||||
|
AS_HELP_STRING([--disable-float], [Disable floating-point API]),, |
||||||
|
enable_float=yes) |
||||||
|
|
||||||
|
AS_IF([test "$enable_float" = "no"], |
||||||
|
[enable_fixed_point=yes |
||||||
|
AC_DEFINE([OP_DISABLE_FLOAT_API], [1], [Disable floating-point API]) |
||||||
|
] |
||||||
|
) |
||||||
|
|
||||||
|
AS_IF([test "$enable_fixed_point" = "yes"], |
||||||
|
[AC_DEFINE([OP_FIXED_POINT], [1], [Enable fixed-point calculation])], |
||||||
|
[dnl This only has to be tested for if float->fixed conversions are required |
||||||
|
saved_LIBS="$LIBS" |
||||||
|
AC_SEARCH_LIBS([lrintf], [m], [ |
||||||
|
AC_DEFINE([OP_HAVE_LRINTF], [1], [Enable use of lrintf function]) |
||||||
|
lrintf_notice=" |
||||||
|
Library for lrintf() ......... ${ac_cv_search_lrintf}" |
||||||
|
]) |
||||||
|
LIBS="$saved_LIBS" |
||||||
|
] |
||||||
|
) |
||||||
|
|
||||||
|
AC_ARG_ENABLE([examples], |
||||||
|
AS_HELP_STRING([--disable-examples], [Do not build example applications]),, |
||||||
|
enable_examples=yes) |
||||||
|
AM_CONDITIONAL([OP_ENABLE_EXAMPLES], [test "$enable_examples" = "yes"]) |
||||||
|
|
||||||
|
AS_CASE(["$ac_cv_search_lrintf"], |
||||||
|
["no"],[], |
||||||
|
["none required"],[], |
||||||
|
[lrintf_lib="$ac_cv_search_lrintf"]) |
||||||
|
|
||||||
|
AC_SUBST([lrintf_lib]) |
||||||
|
|
||||||
|
CC_ATTRIBUTE_VISIBILITY([default], [ |
||||||
|
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl Check for doxygen |
||||||
|
AC_ARG_ENABLE([doc], |
||||||
|
AS_HELP_STRING([--disable-doc], [Do not build API documentation]),, |
||||||
|
[enable_doc=yes] |
||||||
|
) |
||||||
|
|
||||||
|
AS_IF([test "$enable_doc" = "yes"], [ |
||||||
|
AC_CHECK_PROG([HAVE_DOXYGEN], [doxygen], [yes], [no]) |
||||||
|
AC_CHECK_PROG([HAVE_DOT], [dot], [yes], [no]) |
||||||
|
],[ |
||||||
|
HAVE_DOXYGEN=no |
||||||
|
]) |
||||||
|
|
||||||
|
AM_CONDITIONAL([HAVE_DOXYGEN], [test "$HAVE_DOXYGEN" = "yes"]) |
||||||
|
|
||||||
|
AC_CONFIG_FILES([ |
||||||
|
Makefile |
||||||
|
opusfile.pc |
||||||
|
opusurl.pc |
||||||
|
opusfile-uninstalled.pc |
||||||
|
opusurl-uninstalled.pc |
||||||
|
doc/Doxyfile |
||||||
|
]) |
||||||
|
AC_CONFIG_HEADERS([config.h]) |
||||||
|
AC_OUTPUT |
||||||
|
|
||||||
|
AC_MSG_NOTICE([ |
||||||
|
------------------------------------------------------------------------ |
||||||
|
$PACKAGE_NAME $PACKAGE_VERSION: Automatic configuration OK. |
||||||
|
|
||||||
|
Assertions ................... ${enable_assertions} |
||||||
|
|
||||||
|
HTTP support ................. ${enable_http} |
||||||
|
Fixed-point .................. ${enable_fixed_point} |
||||||
|
Floating-point API ........... ${enable_float}${lrintf_notice} |
||||||
|
|
||||||
|
Hidden visibility ............ ${cc_cv_flag_visibility} |
||||||
|
|
||||||
|
API code examples ............ ${enable_examples} |
||||||
|
API documentation ............ ${enable_doc} |
||||||
|
------------------------------------------------------------------------ |
||||||
|
]) |
@ -0,0 +1,791 @@ |
|||||||
|
#! /bin/sh |
||||||
|
# depcomp - compile a program generating dependencies as side-effects |
||||||
|
|
||||||
|
scriptversion=2018-03-07.03; # UTC |
||||||
|
|
||||||
|
# Copyright (C) 1999-2020 Free Software Foundation, Inc. |
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2, or (at your option) |
||||||
|
# any later version. |
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you |
||||||
|
# distribute this file as part of a program that contains a |
||||||
|
# configuration script generated by Autoconf, you may include it under |
||||||
|
# the same distribution terms that you use for the rest of that program. |
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. |
||||||
|
|
||||||
|
case $1 in |
||||||
|
'') |
||||||
|
echo "$0: No command. Try '$0 --help' for more information." 1>&2 |
||||||
|
exit 1; |
||||||
|
;; |
||||||
|
-h | --h*) |
||||||
|
cat <<\EOF |
||||||
|
Usage: depcomp [--help] [--version] PROGRAM [ARGS] |
||||||
|
|
||||||
|
Run PROGRAMS ARGS to compile a file, generating dependencies |
||||||
|
as side-effects. |
||||||
|
|
||||||
|
Environment variables: |
||||||
|
depmode Dependency tracking mode. |
||||||
|
source Source file read by 'PROGRAMS ARGS'. |
||||||
|
object Object file output by 'PROGRAMS ARGS'. |
||||||
|
DEPDIR directory where to store dependencies. |
||||||
|
depfile Dependency file to output. |
||||||
|
tmpdepfile Temporary file to use when outputting dependencies. |
||||||
|
libtool Whether libtool is used (yes/no). |
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>. |
||||||
|
EOF |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
-v | --v*) |
||||||
|
echo "depcomp $scriptversion" |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
# Get the directory component of the given path, and save it in the |
||||||
|
# global variables '$dir'. Note that this directory component will |
||||||
|
# be either empty or ending with a '/' character. This is deliberate. |
||||||
|
set_dir_from () |
||||||
|
{ |
||||||
|
case $1 in |
||||||
|
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; |
||||||
|
*) dir=;; |
||||||
|
esac |
||||||
|
} |
||||||
|
|
||||||
|
# Get the suffix-stripped basename of the given path, and save it the |
||||||
|
# global variable '$base'. |
||||||
|
set_base_from () |
||||||
|
{ |
||||||
|
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` |
||||||
|
} |
||||||
|
|
||||||
|
# If no dependency file was actually created by the compiler invocation, |
||||||
|
# we still have to create a dummy depfile, to avoid errors with the |
||||||
|
# Makefile "include basename.Plo" scheme. |
||||||
|
make_dummy_depfile () |
||||||
|
{ |
||||||
|
echo "#dummy" > "$depfile" |
||||||
|
} |
||||||
|
|
||||||
|
# Factor out some common post-processing of the generated depfile. |
||||||
|
# Requires the auxiliary global variable '$tmpdepfile' to be set. |
||||||
|
aix_post_process_depfile () |
||||||
|
{ |
||||||
|
# If the compiler actually managed to produce a dependency file, |
||||||
|
# post-process it. |
||||||
|
if test -f "$tmpdepfile"; then |
||||||
|
# Each line is of the form 'foo.o: dependency.h'. |
||||||
|
# Do two passes, one to just change these to |
||||||
|
# $object: dependency.h |
||||||
|
# and one to simply output |
||||||
|
# dependency.h: |
||||||
|
# which is needed to avoid the deleted-header problem. |
||||||
|
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" |
||||||
|
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" |
||||||
|
} > "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
else |
||||||
|
make_dummy_depfile |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# A tabulation character. |
||||||
|
tab=' ' |
||||||
|
# A newline character. |
||||||
|
nl=' |
||||||
|
' |
||||||
|
# Character ranges might be problematic outside the C locale. |
||||||
|
# These definitions help. |
||||||
|
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ |
||||||
|
lower=abcdefghijklmnopqrstuvwxyz |
||||||
|
digits=0123456789 |
||||||
|
alpha=${upper}${lower} |
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then |
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. |
||||||
|
depfile=${depfile-`echo "$object" | |
||||||
|
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} |
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} |
||||||
|
|
||||||
|
rm -f "$tmpdepfile" |
||||||
|
|
||||||
|
# Avoid interferences from the environment. |
||||||
|
gccflag= dashmflag= |
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We |
||||||
|
# parameterize here, but still list the modes in the big case below, |
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case |
||||||
|
# here, because this file can only contain one case statement. |
||||||
|
if test "$depmode" = hp; then |
||||||
|
# HP compiler uses -M and no extra arg. |
||||||
|
gccflag=-M |
||||||
|
depmode=gcc |
||||||
|
fi |
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then |
||||||
|
# This is just like dashmstdout with a different argument. |
||||||
|
dashmflag=-xM |
||||||
|
depmode=dashmstdout |
||||||
|
fi |
||||||
|
|
||||||
|
cygpath_u="cygpath -u -f -" |
||||||
|
if test "$depmode" = msvcmsys; then |
||||||
|
# This is just like msvisualcpp but w/o cygpath translation. |
||||||
|
# Just convert the backslash-escaped backslashes to single forward |
||||||
|
# slashes to satisfy depend.m4 |
||||||
|
cygpath_u='sed s,\\\\,/,g' |
||||||
|
depmode=msvisualcpp |
||||||
|
fi |
||||||
|
|
||||||
|
if test "$depmode" = msvc7msys; then |
||||||
|
# This is just like msvc7 but w/o cygpath translation. |
||||||
|
# Just convert the backslash-escaped backslashes to single forward |
||||||
|
# slashes to satisfy depend.m4 |
||||||
|
cygpath_u='sed s,\\\\,/,g' |
||||||
|
depmode=msvc7 |
||||||
|
fi |
||||||
|
|
||||||
|
if test "$depmode" = xlc; then |
||||||
|
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. |
||||||
|
gccflag=-qmakedep=gcc,-MF |
||||||
|
depmode=gcc |
||||||
|
fi |
||||||
|
|
||||||
|
case "$depmode" in |
||||||
|
gcc3) |
||||||
|
## gcc 3 implements dependency tracking that does exactly what |
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like |
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm. |
||||||
|
## Unfortunately, FreeBSD c89 acceptance of flags depends upon |
||||||
|
## the command line argument order; so add the flags where they |
||||||
|
## appear in depend2.am. Note that the slowdown incurred here |
||||||
|
## affects only configure: in makefiles, %FASTDEP% shortcuts this. |
||||||
|
for arg |
||||||
|
do |
||||||
|
case $arg in |
||||||
|
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; |
||||||
|
*) set fnord "$@" "$arg" ;; |
||||||
|
esac |
||||||
|
shift # fnord |
||||||
|
shift # $arg |
||||||
|
done |
||||||
|
"$@" |
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
mv "$tmpdepfile" "$depfile" |
||||||
|
;; |
||||||
|
|
||||||
|
gcc) |
||||||
|
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. |
||||||
|
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. |
||||||
|
## (see the conditional assignment to $gccflag above). |
||||||
|
## There are various ways to get dependency output from gcc. Here's |
||||||
|
## why we pick this rather obscure method: |
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end |
||||||
|
## up in a subdir. Having to rename by hand is ugly. |
||||||
|
## (We might end up doing this anyway to support other compilers.) |
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like |
||||||
|
## -MM, not -M (despite what the docs say). Also, it might not be |
||||||
|
## supported by the other compilers which use the 'gcc' depmode. |
||||||
|
## - Using -M directly means running the compiler twice (even worse |
||||||
|
## than renaming). |
||||||
|
if test -z "$gccflag"; then |
||||||
|
gccflag=-MD, |
||||||
|
fi |
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile" |
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
rm -f "$depfile" |
||||||
|
echo "$object : \\" > "$depfile" |
||||||
|
# The second -e expression handles DOS-style file names with drive |
||||||
|
# letters. |
||||||
|
sed -e 's/^[^:]*: / /' \ |
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" |
||||||
|
## This next piece of magic avoids the "deleted header file" problem. |
||||||
|
## The problem is that when a header file which appears in a .P file |
||||||
|
## is deleted, the dependency causes make to die (because there is |
||||||
|
## typically no way to rebuild the header). We avoid this by adding |
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do |
||||||
|
## this for us directly. |
||||||
|
## Some versions of gcc put a space before the ':'. On the theory |
||||||
|
## that the space means something, we add a space to the output as |
||||||
|
## well. hp depmode also adds that space, but also prefixes the VPATH |
||||||
|
## to the object. Take care to not repeat it in the output. |
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation |
||||||
|
## correctly. Breaking it into two sed invocations is a workaround. |
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \ |
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ |
||||||
|
| sed -e 's/$/ :/' >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
hp) |
||||||
|
# This case exists only to let depend.m4 do its work. It works by |
||||||
|
# looking at the text of this script. This case will never be run, |
||||||
|
# since it is checked for above. |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
|
||||||
|
sgi) |
||||||
|
if test "$libtool" = yes; then |
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile" |
||||||
|
else |
||||||
|
"$@" -MDupdate "$tmpdepfile" |
||||||
|
fi |
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
rm -f "$depfile" |
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files |
||||||
|
echo "$object : \\" > "$depfile" |
||||||
|
# Clip off the initial element (the dependent). Don't try to be |
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle |
||||||
|
# lines with more than a fixed number of characters (4096 in |
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; |
||||||
|
# the IRIX cc adds comments like '#:fec' to the end of the |
||||||
|
# dependency line. |
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \ |
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ |
||||||
|
| tr "$nl" ' ' >> "$depfile" |
||||||
|
echo >> "$depfile" |
||||||
|
# The second pass generates a dummy entry for each header file. |
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \ |
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ |
||||||
|
>> "$depfile" |
||||||
|
else |
||||||
|
make_dummy_depfile |
||||||
|
fi |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
xlc) |
||||||
|
# This case exists only to let depend.m4 do its work. It works by |
||||||
|
# looking at the text of this script. This case will never be run, |
||||||
|
# since it is checked for above. |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
|
||||||
|
aix) |
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies |
||||||
|
# in a .u file. In older versions, this file always lives in the |
||||||
|
# current directory. Also, the AIX compiler puts '$object:' at the |
||||||
|
# start of each line; $object doesn't have directory information. |
||||||
|
# Version 6 uses the directory in both cases. |
||||||
|
set_dir_from "$object" |
||||||
|
set_base_from "$object" |
||||||
|
if test "$libtool" = yes; then |
||||||
|
tmpdepfile1=$dir$base.u |
||||||
|
tmpdepfile2=$base.u |
||||||
|
tmpdepfile3=$dir.libs/$base.u |
||||||
|
"$@" -Wc,-M |
||||||
|
else |
||||||
|
tmpdepfile1=$dir$base.u |
||||||
|
tmpdepfile2=$dir$base.u |
||||||
|
tmpdepfile3=$dir$base.u |
||||||
|
"$@" -M |
||||||
|
fi |
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" |
||||||
|
do |
||||||
|
test -f "$tmpdepfile" && break |
||||||
|
done |
||||||
|
aix_post_process_depfile |
||||||
|
;; |
||||||
|
|
||||||
|
tcc) |
||||||
|
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 |
||||||
|
# FIXME: That version still under development at the moment of writing. |
||||||
|
# Make that this statement remains true also for stable, released |
||||||
|
# versions. |
||||||
|
# It will wrap lines (doesn't matter whether long or short) with a |
||||||
|
# trailing '\', as in: |
||||||
|
# |
||||||
|
# foo.o : \ |
||||||
|
# foo.c \ |
||||||
|
# foo.h \ |
||||||
|
# |
||||||
|
# It will put a trailing '\' even on the last line, and will use leading |
||||||
|
# spaces rather than leading tabs (at least since its commit 0394caf7 |
||||||
|
# "Emit spaces for -MD"). |
||||||
|
"$@" -MD -MF "$tmpdepfile" |
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
rm -f "$depfile" |
||||||
|
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. |
||||||
|
# We have to change lines of the first kind to '$object: \'. |
||||||
|
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" |
||||||
|
# And for each line of the second kind, we have to emit a 'dep.h:' |
||||||
|
# dummy dependency, to avoid the deleted-header problem. |
||||||
|
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
## The order of this option in the case statement is important, since the |
||||||
|
## shell code in configure will try each of these formats in the order |
||||||
|
## listed in this file. A plain '-MD' option would be understood by many |
||||||
|
## compilers, so we must ensure this comes after the gcc and icc options. |
||||||
|
pgcc) |
||||||
|
# Portland's C compiler understands '-MD'. |
||||||
|
# Will always output deps to 'file.d' where file is the root name of the |
||||||
|
# source file under compilation, even if file resides in a subdirectory. |
||||||
|
# The object file name does not affect the name of the '.d' file. |
||||||
|
# pgcc 10.2 will output |
||||||
|
# foo.o: sub/foo.c sub/foo.h |
||||||
|
# and will wrap long lines using '\' : |
||||||
|
# foo.o: sub/foo.c ... \ |
||||||
|
# sub/foo.h ... \ |
||||||
|
# ... |
||||||
|
set_dir_from "$object" |
||||||
|
# Use the source, not the object, to determine the base name, since |
||||||
|
# that's sadly what pgcc will do too. |
||||||
|
set_base_from "$source" |
||||||
|
tmpdepfile=$base.d |
||||||
|
|
||||||
|
# For projects that build the same source file twice into different object |
||||||
|
# files, the pgcc approach of using the *source* file root name can cause |
||||||
|
# problems in parallel builds. Use a locking strategy to avoid stomping on |
||||||
|
# the same $tmpdepfile. |
||||||
|
lockdir=$base.d-lock |
||||||
|
trap " |
||||||
|
echo '$0: caught signal, cleaning up...' >&2 |
||||||
|
rmdir '$lockdir' |
||||||
|
exit 1 |
||||||
|
" 1 2 13 15 |
||||||
|
numtries=100 |
||||||
|
i=$numtries |
||||||
|
while test $i -gt 0; do |
||||||
|
# mkdir is a portable test-and-set. |
||||||
|
if mkdir "$lockdir" 2>/dev/null; then |
||||||
|
# This process acquired the lock. |
||||||
|
"$@" -MD |
||||||
|
stat=$? |
||||||
|
# Release the lock. |
||||||
|
rmdir "$lockdir" |
||||||
|
break |
||||||
|
else |
||||||
|
# If the lock is being held by a different process, wait |
||||||
|
# until the winning process is done or we timeout. |
||||||
|
while test -d "$lockdir" && test $i -gt 0; do |
||||||
|
sleep 1 |
||||||
|
i=`expr $i - 1` |
||||||
|
done |
||||||
|
fi |
||||||
|
i=`expr $i - 1` |
||||||
|
done |
||||||
|
trap - 1 2 13 15 |
||||||
|
if test $i -le 0; then |
||||||
|
echo "$0: failed to acquire lock after $numtries attempts" >&2 |
||||||
|
echo "$0: check lockdir '$lockdir'" >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
rm -f "$depfile" |
||||||
|
# Each line is of the form `foo.o: dependent.h', |
||||||
|
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. |
||||||
|
# Do two passes, one to just change these to |
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'. |
||||||
|
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" |
||||||
|
# Some versions of the HPUX 10.20 sed can't process this invocation |
||||||
|
# correctly. Breaking it into two sed invocations is a workaround. |
||||||
|
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ |
||||||
|
| sed -e 's/$/ :/' >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
hp2) |
||||||
|
# The "hp" stanza above does not work with aCC (C++) and HP's ia64 |
||||||
|
# compilers, which have integrated preprocessors. The correct option |
||||||
|
# to use with these is +Maked; it writes dependencies to a file named |
||||||
|
# 'foo.d', which lands next to the object file, wherever that |
||||||
|
# happens to be. |
||||||
|
# Much of this is similar to the tru64 case; see comments there. |
||||||
|
set_dir_from "$object" |
||||||
|
set_base_from "$object" |
||||||
|
if test "$libtool" = yes; then |
||||||
|
tmpdepfile1=$dir$base.d |
||||||
|
tmpdepfile2=$dir.libs/$base.d |
||||||
|
"$@" -Wc,+Maked |
||||||
|
else |
||||||
|
tmpdepfile1=$dir$base.d |
||||||
|
tmpdepfile2=$dir$base.d |
||||||
|
"$@" +Maked |
||||||
|
fi |
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" |
||||||
|
do |
||||||
|
test -f "$tmpdepfile" && break |
||||||
|
done |
||||||
|
if test -f "$tmpdepfile"; then |
||||||
|
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" |
||||||
|
# Add 'dependent.h:' lines. |
||||||
|
sed -ne '2,${ |
||||||
|
s/^ *// |
||||||
|
s/ \\*$// |
||||||
|
s/$/:/ |
||||||
|
p |
||||||
|
}' "$tmpdepfile" >> "$depfile" |
||||||
|
else |
||||||
|
make_dummy_depfile |
||||||
|
fi |
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile2" |
||||||
|
;; |
||||||
|
|
||||||
|
tru64) |
||||||
|
# The Tru64 compiler uses -MD to generate dependencies as a side |
||||||
|
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. |
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put |
||||||
|
# dependencies in 'foo.d' instead, so we check for that too. |
||||||
|
# Subdirectories are respected. |
||||||
|
set_dir_from "$object" |
||||||
|
set_base_from "$object" |
||||||
|
|
||||||
|
if test "$libtool" = yes; then |
||||||
|
# Libtool generates 2 separate objects for the 2 libraries. These |
||||||
|
# two compilations output dependencies in $dir.libs/$base.o.d and |
||||||
|
# in $dir$base.o.d. We have to check for both files, because |
||||||
|
# one of the two compilations can be disabled. We should prefer |
||||||
|
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is |
||||||
|
# automatically cleaned when .libs/ is deleted, while ignoring |
||||||
|
# the former would cause a distcleancheck panic. |
||||||
|
tmpdepfile1=$dir$base.o.d # libtool 1.5 |
||||||
|
tmpdepfile2=$dir.libs/$base.o.d # Likewise. |
||||||
|
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 |
||||||
|
"$@" -Wc,-MD |
||||||
|
else |
||||||
|
tmpdepfile1=$dir$base.d |
||||||
|
tmpdepfile2=$dir$base.d |
||||||
|
tmpdepfile3=$dir$base.d |
||||||
|
"$@" -MD |
||||||
|
fi |
||||||
|
|
||||||
|
stat=$? |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" |
||||||
|
do |
||||||
|
test -f "$tmpdepfile" && break |
||||||
|
done |
||||||
|
# Same post-processing that is required for AIX mode. |
||||||
|
aix_post_process_depfile |
||||||
|
;; |
||||||
|
|
||||||
|
msvc7) |
||||||
|
if test "$libtool" = yes; then |
||||||
|
showIncludes=-Wc,-showIncludes |
||||||
|
else |
||||||
|
showIncludes=-showIncludes |
||||||
|
fi |
||||||
|
"$@" $showIncludes > "$tmpdepfile" |
||||||
|
stat=$? |
||||||
|
grep -v '^Note: including file: ' "$tmpdepfile" |
||||||
|
if test $stat -ne 0; then |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
exit $stat |
||||||
|
fi |
||||||
|
rm -f "$depfile" |
||||||
|
echo "$object : \\" > "$depfile" |
||||||
|
# The first sed program below extracts the file names and escapes |
||||||
|
# backslashes for cygpath. The second sed program outputs the file |
||||||
|
# name when reading, but also accumulates all include files in the |
||||||
|
# hold buffer in order to output them again at the end. This only |
||||||
|
# works with sed implementations that can handle large buffers. |
||||||
|
sed < "$tmpdepfile" -n ' |
||||||
|
/^Note: including file: *\(.*\)/ { |
||||||
|
s//\1/ |
||||||
|
s/\\/\\\\/g |
||||||
|
p |
||||||
|
}' | $cygpath_u | sort -u | sed -n ' |
||||||
|
s/ /\\ /g |
||||||
|
s/\(.*\)/'"$tab"'\1 \\/p |
||||||
|
s/.\(.*\) \\/\1:/ |
||||||
|
H |
||||||
|
$ { |
||||||
|
s/.*/'"$tab"'/ |
||||||
|
G |
||||||
|
p |
||||||
|
}' >> "$depfile" |
||||||
|
echo >> "$depfile" # make sure the fragment doesn't end with a backslash |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
msvc7msys) |
||||||
|
# This case exists only to let depend.m4 do its work. It works by |
||||||
|
# looking at the text of this script. This case will never be run, |
||||||
|
# since it is checked for above. |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
|
||||||
|
#nosideeffect) |
||||||
|
# This comment above is used by automake to tell side-effect |
||||||
|
# dependency tracking mechanisms from slower ones. |
||||||
|
|
||||||
|
dashmstdout) |
||||||
|
# Important note: in order to support this mode, a compiler *must* |
||||||
|
# always write the preprocessed file to stdout, regardless of -o. |
||||||
|
"$@" || exit $? |
||||||
|
|
||||||
|
# Remove the call to Libtool. |
||||||
|
if test "$libtool" = yes; then |
||||||
|
while test "X$1" != 'X--mode=compile'; do |
||||||
|
shift |
||||||
|
done |
||||||
|
shift |
||||||
|
fi |
||||||
|
|
||||||
|
# Remove '-o $object'. |
||||||
|
IFS=" " |
||||||
|
for arg |
||||||
|
do |
||||||
|
case $arg in |
||||||
|
-o) |
||||||
|
shift |
||||||
|
;; |
||||||
|
$object) |
||||||
|
shift |
||||||
|
;; |
||||||
|
*) |
||||||
|
set fnord "$@" "$arg" |
||||||
|
shift # fnord |
||||||
|
shift # $arg |
||||||
|
;; |
||||||
|
esac |
||||||
|
done |
||||||
|
|
||||||
|
test -z "$dashmflag" && dashmflag=-M |
||||||
|
# Require at least two characters before searching for ':' |
||||||
|
# in the target name. This is to cope with DOS-style filenames: |
||||||
|
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. |
||||||
|
"$@" $dashmflag | |
||||||
|
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" |
||||||
|
rm -f "$depfile" |
||||||
|
cat < "$tmpdepfile" > "$depfile" |
||||||
|
# Some versions of the HPUX 10.20 sed can't process this sed invocation |
||||||
|
# correctly. Breaking it into two sed invocations is a workaround. |
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \ |
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ |
||||||
|
| sed -e 's/$/ :/' >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
dashXmstdout) |
||||||
|
# This case only exists to satisfy depend.m4. It is never actually |
||||||
|
# run, as this mode is specially recognized in the preamble. |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
|
||||||
|
makedepend) |
||||||
|
"$@" || exit $? |
||||||
|
# Remove any Libtool call |
||||||
|
if test "$libtool" = yes; then |
||||||
|
while test "X$1" != 'X--mode=compile'; do |
||||||
|
shift |
||||||
|
done |
||||||
|
shift |
||||||
|
fi |
||||||
|
# X makedepend |
||||||
|
shift |
||||||
|
cleared=no eat=no |
||||||
|
for arg |
||||||
|
do |
||||||
|
case $cleared in |
||||||
|
no) |
||||||
|
set ""; shift |
||||||
|
cleared=yes ;; |
||||||
|
esac |
||||||
|
if test $eat = yes; then |
||||||
|
eat=no |
||||||
|
continue |
||||||
|
fi |
||||||
|
case "$arg" in |
||||||
|
-D*|-I*) |
||||||
|
set fnord "$@" "$arg"; shift ;; |
||||||
|
# Strip any option that makedepend may not understand. Remove |
||||||
|
# the object too, otherwise makedepend will parse it as a source file. |
||||||
|
-arch) |
||||||
|
eat=yes ;; |
||||||
|
-*|$object) |
||||||
|
;; |
||||||
|
*) |
||||||
|
set fnord "$@" "$arg"; shift ;; |
||||||
|
esac |
||||||
|
done |
||||||
|
obj_suffix=`echo "$object" | sed 's/^.*\././'` |
||||||
|
touch "$tmpdepfile" |
||||||
|
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" |
||||||
|
rm -f "$depfile" |
||||||
|
# makedepend may prepend the VPATH from the source file name to the object. |
||||||
|
# No need to regex-escape $object, excess matching of '.' is harmless. |
||||||
|
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" |
||||||
|
# Some versions of the HPUX 10.20 sed can't process the last invocation |
||||||
|
# correctly. Breaking it into two sed invocations is a workaround. |
||||||
|
sed '1,2d' "$tmpdepfile" \ |
||||||
|
| tr ' ' "$nl" \ |
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ |
||||||
|
| sed -e 's/$/ :/' >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak |
||||||
|
;; |
||||||
|
|
||||||
|
cpp) |
||||||
|
# Important note: in order to support this mode, a compiler *must* |
||||||
|
# always write the preprocessed file to stdout. |
||||||
|
"$@" || exit $? |
||||||
|
|
||||||
|
# Remove the call to Libtool. |
||||||
|
if test "$libtool" = yes; then |
||||||
|
while test "X$1" != 'X--mode=compile'; do |
||||||
|
shift |
||||||
|
done |
||||||
|
shift |
||||||
|
fi |
||||||
|
|
||||||
|
# Remove '-o $object'. |
||||||
|
IFS=" " |
||||||
|
for arg |
||||||
|
do |
||||||
|
case $arg in |
||||||
|
-o) |
||||||
|
shift |
||||||
|
;; |
||||||
|
$object) |
||||||
|
shift |
||||||
|
;; |
||||||
|
*) |
||||||
|
set fnord "$@" "$arg" |
||||||
|
shift # fnord |
||||||
|
shift # $arg |
||||||
|
;; |
||||||
|
esac |
||||||
|
done |
||||||
|
|
||||||
|
"$@" -E \ |
||||||
|
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ |
||||||
|
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ |
||||||
|
| sed '$ s: \\$::' > "$tmpdepfile" |
||||||
|
rm -f "$depfile" |
||||||
|
echo "$object : \\" > "$depfile" |
||||||
|
cat < "$tmpdepfile" >> "$depfile" |
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
msvisualcpp) |
||||||
|
# Important note: in order to support this mode, a compiler *must* |
||||||
|
# always write the preprocessed file to stdout. |
||||||
|
"$@" || exit $? |
||||||
|
|
||||||
|
# Remove the call to Libtool. |
||||||
|
if test "$libtool" = yes; then |
||||||
|
while test "X$1" != 'X--mode=compile'; do |
||||||
|
shift |
||||||
|
done |
||||||
|
shift |
||||||
|
fi |
||||||
|
|
||||||
|
IFS=" " |
||||||
|
for arg |
||||||
|
do |
||||||
|
case "$arg" in |
||||||
|
-o) |
||||||
|
shift |
||||||
|
;; |
||||||
|
$object) |
||||||
|
shift |
||||||
|
;; |
||||||
|
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") |
||||||
|
set fnord "$@" |
||||||
|
shift |
||||||
|
shift |
||||||
|
;; |
||||||
|
*) |
||||||
|
set fnord "$@" "$arg" |
||||||
|
shift |
||||||
|
shift |
||||||
|
;; |
||||||
|
esac |
||||||
|
done |
||||||
|
"$@" -E 2>/dev/null | |
||||||
|
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" |
||||||
|
rm -f "$depfile" |
||||||
|
echo "$object : \\" > "$depfile" |
||||||
|
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" |
||||||
|
echo "$tab" >> "$depfile" |
||||||
|
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" |
||||||
|
rm -f "$tmpdepfile" |
||||||
|
;; |
||||||
|
|
||||||
|
msvcmsys) |
||||||
|
# This case exists only to let depend.m4 do its work. It works by |
||||||
|
# looking at the text of this script. This case will never be run, |
||||||
|
# since it is checked for above. |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
|
||||||
|
none) |
||||||
|
exec "$@" |
||||||
|
;; |
||||||
|
|
||||||
|
*) |
||||||
|
echo "Unknown depmode $depmode" 1>&2 |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
exit 0 |
||||||
|
|
||||||
|
# Local Variables: |
||||||
|
# mode: shell-script |
||||||
|
# sh-indentation: 2 |
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp) |
||||||
|
# time-stamp-start: "scriptversion=" |
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H" |
||||||
|
# time-stamp-time-zone: "UTC0" |
||||||
|
# time-stamp-end: "; # UTC" |
||||||
|
# End: |
@ -0,0 +1,22 @@ |
|||||||
|
# Process with doxygen to generate API documentation |
||||||
|
|
||||||
|
PROJECT_NAME = @PACKAGE_NAME@ |
||||||
|
PROJECT_NUMBER = @PACKAGE_VERSION@ |
||||||
|
PROJECT_BRIEF = "Stand-alone decoder library for .opus files." |
||||||
|
INPUT = @top_srcdir@/include/opusfile.h |
||||||
|
OPTIMIZE_OUTPUT_FOR_C = YES |
||||||
|
|
||||||
|
QUIET = YES |
||||||
|
WARNINGS = YES |
||||||
|
WARN_IF_UNDOCUMENTED = YES |
||||||
|
WARN_IF_DOC_ERROR = YES |
||||||
|
WARN_NO_PARAMDOC = YES |
||||||
|
|
||||||
|
JAVADOC_AUTOBRIEF = YES |
||||||
|
SORT_MEMBER_DOCS = NO |
||||||
|
|
||||||
|
HAVE_DOT = @HAVE_DOT@ |
||||||
|
|
||||||
|
PROJECT_LOGO = @top_srcdir@/doc/opus_logo.svg |
||||||
|
|
||||||
|
FULL_PATH_NAMES = NO |
@ -0,0 +1,35 @@ |
|||||||
|
## GNU makefile for opusfile documentation.
|
||||||
|
|
||||||
|
-include ../package_version |
||||||
|
|
||||||
|
all: doxygen |
||||||
|
|
||||||
|
doxygen: Doxyfile ../include/opusfile.h |
||||||
|
doxygen
|
||||||
|
|
||||||
|
pdf: doxygen |
||||||
|
make -C latex
|
||||||
|
|
||||||
|
clean: |
||||||
|
$(RM) -r html
|
||||||
|
$(RM) -r latex
|
||||||
|
|
||||||
|
distclean: clean |
||||||
|
$(RM) Doxyfile
|
||||||
|
|
||||||
|
.PHONY: all clean distclean doxygen pdf |
||||||
|
|
||||||
|
../package_version: |
||||||
|
@if [ -x ../update_version ]; then \
|
||||||
|
../update_version || true; \
|
||||||
|
elif [ ! -e $@ ]; then \
|
||||||
|
echo 'PACKAGE_VERSION="unknown"' > $@; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# run autoconf-like replacements to finalize our config
|
||||||
|
Doxyfile: Doxyfile.in Makefile ../package_version |
||||||
|
sed -e 's/@PACKAGE_NAME@/opusfile/' \
|
||||||
|
-e 's/@PACKAGE_VERSION@/$(PACKAGE_VERSION)/' \
|
||||||
|
-e 's/@HAVE_DOT@/yes/' \
|
||||||
|
-e 's/@top_srcdir@/../' \
|
||||||
|
< $< > $@
|
After Width: | Height: | Size: 8.4 KiB |
@ -0,0 +1,390 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H |
||||||
|
#include "config.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
/*For fileno()*/ |
||||||
|
#if !defined(_POSIX_SOURCE) |
||||||
|
# define _POSIX_SOURCE 1 |
||||||
|
#endif |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <errno.h> |
||||||
|
#include <string.h> |
||||||
|
#include <opusfile.h> |
||||||
|
#if defined(_WIN32) |
||||||
|
# include "win32utf8.h" |
||||||
|
# undef fileno |
||||||
|
# define fileno _fileno |
||||||
|
#endif |
||||||
|
|
||||||
|
static void print_duration(FILE *_fp,ogg_int64_t _nsamples,int _frac){ |
||||||
|
ogg_int64_t seconds; |
||||||
|
ogg_int64_t minutes; |
||||||
|
ogg_int64_t hours; |
||||||
|
ogg_int64_t days; |
||||||
|
ogg_int64_t weeks; |
||||||
|
_nsamples+=_frac?24:24000; |
||||||
|
seconds=_nsamples/48000; |
||||||
|
_nsamples-=seconds*48000; |
||||||
|
minutes=seconds/60; |
||||||
|
seconds-=minutes*60; |
||||||
|
hours=minutes/60; |
||||||
|
minutes-=hours*60; |
||||||
|
days=hours/24; |
||||||
|
hours-=days*24; |
||||||
|
weeks=days/7; |
||||||
|
days-=weeks*7; |
||||||
|
if(weeks)fprintf(_fp,"%liw",(long)weeks); |
||||||
|
if(weeks||days)fprintf(_fp,"%id",(int)days); |
||||||
|
if(weeks||days||hours){ |
||||||
|
if(weeks||days)fprintf(_fp,"%02ih",(int)hours); |
||||||
|
else fprintf(_fp,"%ih",(int)hours); |
||||||
|
} |
||||||
|
if(weeks||days||hours||minutes){ |
||||||
|
if(weeks||days||hours)fprintf(_fp,"%02im",(int)minutes); |
||||||
|
else fprintf(_fp,"%im",(int)minutes); |
||||||
|
fprintf(_fp,"%02i",(int)seconds); |
||||||
|
} |
||||||
|
else fprintf(_fp,"%i",(int)seconds); |
||||||
|
if(_frac)fprintf(_fp,".%03i",(int)(_nsamples/48)); |
||||||
|
fprintf(_fp,"s"); |
||||||
|
} |
||||||
|
|
||||||
|
static void print_size(FILE *_fp,opus_int64 _nbytes,int _metric, |
||||||
|
const char *_spacer){ |
||||||
|
static const char SUFFIXES[7]={' ','k','M','G','T','P','E'}; |
||||||
|
opus_int64 val; |
||||||
|
opus_int64 den; |
||||||
|
opus_int64 round; |
||||||
|
int base; |
||||||
|
int shift; |
||||||
|
base=_metric?1000:1024; |
||||||
|
round=0; |
||||||
|
den=1; |
||||||
|
for(shift=0;shift<6;shift++){ |
||||||
|
if(_nbytes<den*base-round)break; |
||||||
|
den*=base; |
||||||
|
round=den>>1; |
||||||
|
} |
||||||
|
val=(_nbytes+round)/den; |
||||||
|
if(den>1&&val<10){ |
||||||
|
if(den>=1000000000)val=(_nbytes+(round/100))/(den/100); |
||||||
|
else val=(_nbytes*100+round)/den; |
||||||
|
fprintf(_fp,"%li.%02i%s%c",(long)(val/100),(int)(val%100), |
||||||
|
_spacer,SUFFIXES[shift]); |
||||||
|
} |
||||||
|
else if(den>1&&val<100){ |
||||||
|
if(den>=1000000000)val=(_nbytes+(round/10))/(den/10); |
||||||
|
else val=(_nbytes*10+round)/den; |
||||||
|
fprintf(_fp,"%li.%i%s%c",(long)(val/10),(int)(val%10), |
||||||
|
_spacer,SUFFIXES[shift]); |
||||||
|
} |
||||||
|
else fprintf(_fp,"%li%s%c",(long)val,_spacer,SUFFIXES[shift]); |
||||||
|
} |
||||||
|
|
||||||
|
static void put_le32(unsigned char *_dst,opus_uint32 _x){ |
||||||
|
_dst[0]=(unsigned char)(_x&0xFF); |
||||||
|
_dst[1]=(unsigned char)(_x>>8&0xFF); |
||||||
|
_dst[2]=(unsigned char)(_x>>16&0xFF); |
||||||
|
_dst[3]=(unsigned char)(_x>>24&0xFF); |
||||||
|
} |
||||||
|
|
||||||
|
/*Make a header for a 48 kHz, stereo, signed, 16-bit little-endian PCM WAV.*/ |
||||||
|
static void make_wav_header(unsigned char _dst[44],ogg_int64_t _duration){ |
||||||
|
/*The chunk sizes are set to 0x7FFFFFFF by default.
|
||||||
|
Many, though not all, programs will interpret this to mean the duration is |
||||||
|
"undefined", and continue to read from the file so long as there is actual |
||||||
|
data.*/ |
||||||
|
static const unsigned char WAV_HEADER_TEMPLATE[44]={ |
||||||
|
'R','I','F','F',0xFF,0xFF,0xFF,0x7F, |
||||||
|
'W','A','V','E','f','m','t',' ', |
||||||
|
0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00, |
||||||
|
0x80,0xBB,0x00,0x00,0x00,0xEE,0x02,0x00, |
||||||
|
0x04,0x00,0x10,0x00,'d','a','t','a', |
||||||
|
0xFF,0xFF,0xFF,0x7F |
||||||
|
}; |
||||||
|
memcpy(_dst,WAV_HEADER_TEMPLATE,sizeof(WAV_HEADER_TEMPLATE)); |
||||||
|
if(_duration>0){ |
||||||
|
if(_duration>0x1FFFFFF6){ |
||||||
|
fprintf(stderr,"WARNING: WAV output would be larger than 2 GB.\n"); |
||||||
|
fprintf(stderr, |
||||||
|
"Writing non-standard WAV header with invalid chunk sizes.\n"); |
||||||
|
} |
||||||
|
else{ |
||||||
|
opus_uint32 audio_size; |
||||||
|
audio_size=(opus_uint32)(_duration*4); |
||||||
|
put_le32(_dst+4,audio_size+36); |
||||||
|
put_le32(_dst+40,audio_size); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int main(int _argc,const char **_argv){ |
||||||
|
OggOpusFile *of; |
||||||
|
ogg_int64_t duration; |
||||||
|
unsigned char wav_header[44]; |
||||||
|
int ret; |
||||||
|
int is_ssl; |
||||||
|
int output_seekable; |
||||||
|
#if defined(_WIN32) |
||||||
|
win32_utf8_setup(&_argc,&_argv); |
||||||
|
#endif |
||||||
|
if(_argc!=2){ |
||||||
|
fprintf(stderr,"Usage: %s <file.opus>\n",_argv[0]); |
||||||
|
return EXIT_FAILURE; |
||||||
|
} |
||||||
|
is_ssl=0; |
||||||
|
if(strcmp(_argv[1],"-")==0){ |
||||||
|
OpusFileCallbacks cb={NULL,NULL,NULL,NULL}; |
||||||
|
of=op_open_callbacks(op_fdopen(&cb,fileno(stdin),"rb"),&cb,NULL,0,&ret); |
||||||
|
} |
||||||
|
else{ |
||||||
|
OpusServerInfo info; |
||||||
|
/*Try to treat the argument as a URL.*/ |
||||||
|
of=op_open_url(_argv[1],&ret,OP_GET_SERVER_INFO(&info),NULL); |
||||||
|
#if 0 |
||||||
|
if(of==NULL){ |
||||||
|
OpusFileCallbacks cb={NULL,NULL,NULL,NULL}; |
||||||
|
void *fp; |
||||||
|
/*For debugging: force a file to not be seekable.*/ |
||||||
|
fp=op_fopen(&cb,_argv[1],"rb"); |
||||||
|
cb.seek=NULL; |
||||||
|
cb.tell=NULL; |
||||||
|
of=op_open_callbacks(fp,&cb,NULL,0,NULL); |
||||||
|
} |
||||||
|
#else |
||||||
|
if(of==NULL)of=op_open_file(_argv[1],&ret); |
||||||
|
#endif |
||||||
|
else{ |
||||||
|
if(info.name!=NULL){ |
||||||
|
fprintf(stderr,"Station name: %s\n",info.name); |
||||||
|
} |
||||||
|
if(info.description!=NULL){ |
||||||
|
fprintf(stderr,"Station description: %s\n",info.description); |
||||||
|
} |
||||||
|
if(info.genre!=NULL){ |
||||||
|
fprintf(stderr,"Station genre: %s\n",info.genre); |
||||||
|
} |
||||||
|
if(info.url!=NULL){ |
||||||
|
fprintf(stderr,"Station homepage: %s\n",info.url); |
||||||
|
} |
||||||
|
if(info.bitrate_kbps>=0){ |
||||||
|
fprintf(stderr,"Station bitrate: %u kbps\n", |
||||||
|
(unsigned)info.bitrate_kbps); |
||||||
|
} |
||||||
|
if(info.is_public>=0){ |
||||||
|
fprintf(stderr,"%s\n", |
||||||
|
info.is_public?"Station is public.":"Station is private."); |
||||||
|
} |
||||||
|
if(info.server!=NULL){ |
||||||
|
fprintf(stderr,"Server software: %s\n",info.server); |
||||||
|
} |
||||||
|
if(info.content_type!=NULL){ |
||||||
|
fprintf(stderr,"Content-Type: %s\n",info.content_type); |
||||||
|
} |
||||||
|
is_ssl=info.is_ssl; |
||||||
|
opus_server_info_clear(&info); |
||||||
|
} |
||||||
|
} |
||||||
|
if(of==NULL){ |
||||||
|
fprintf(stderr,"Failed to open file '%s': %i\n",_argv[1],ret); |
||||||
|
return EXIT_FAILURE; |
||||||
|
} |
||||||
|
duration=0; |
||||||
|
output_seekable=fseek(stdout,0,SEEK_CUR)!=-1; |
||||||
|
if(op_seekable(of)){ |
||||||
|
opus_int64 size; |
||||||
|
fprintf(stderr,"Total number of links: %i\n",op_link_count(of)); |
||||||
|
duration=op_pcm_total(of,-1); |
||||||
|
fprintf(stderr,"Total duration: "); |
||||||
|
print_duration(stderr,duration,3); |
||||||
|
fprintf(stderr," (%li samples @ 48 kHz)\n",(long)duration); |
||||||
|
size=op_raw_total(of,-1); |
||||||
|
fprintf(stderr,"Total size: "); |
||||||
|
print_size(stderr,size,0,""); |
||||||
|
fprintf(stderr,"\n"); |
||||||
|
} |
||||||
|
else if(!output_seekable){ |
||||||
|
fprintf(stderr,"WARNING: Neither input nor output are seekable.\n"); |
||||||
|
fprintf(stderr, |
||||||
|
"Writing non-standard WAV header with invalid chunk sizes.\n"); |
||||||
|
} |
||||||
|
make_wav_header(wav_header,duration); |
||||||
|
if(!fwrite(wav_header,sizeof(wav_header),1,stdout)){ |
||||||
|
fprintf(stderr,"Error writing WAV header: %s\n",strerror(errno)); |
||||||
|
ret=EXIT_FAILURE; |
||||||
|
} |
||||||
|
else{ |
||||||
|
ogg_int64_t pcm_offset; |
||||||
|
ogg_int64_t pcm_print_offset; |
||||||
|
ogg_int64_t nsamples; |
||||||
|
opus_int32 bitrate; |
||||||
|
int prev_li; |
||||||
|
prev_li=-1; |
||||||
|
nsamples=0; |
||||||
|
pcm_offset=op_pcm_tell(of); |
||||||
|
if(pcm_offset!=0){ |
||||||
|
fprintf(stderr,"Non-zero starting PCM offset: %li\n",(long)pcm_offset); |
||||||
|
} |
||||||
|
pcm_print_offset=pcm_offset-48000; |
||||||
|
bitrate=0; |
||||||
|
for(;;){ |
||||||
|
ogg_int64_t next_pcm_offset; |
||||||
|
opus_int16 pcm[120*48*2]; |
||||||
|
unsigned char out[120*48*2*2]; |
||||||
|
int li; |
||||||
|
int si; |
||||||
|
/*Although we would generally prefer to use the float interface, WAV
|
||||||
|
files with signed, 16-bit little-endian samples are far more |
||||||
|
universally supported, so that's what we output.*/ |
||||||
|
ret=op_read_stereo(of,pcm,sizeof(pcm)/sizeof(*pcm)); |
||||||
|
if(ret==OP_HOLE){ |
||||||
|
fprintf(stderr,"\nHole detected! Corrupt file segment?\n"); |
||||||
|
continue; |
||||||
|
} |
||||||
|
else if(ret<0){ |
||||||
|
fprintf(stderr,"\nError decoding '%s': %i\n",_argv[1],ret); |
||||||
|
if(is_ssl)fprintf(stderr,"Possible truncation attack?\n"); |
||||||
|
ret=EXIT_FAILURE; |
||||||
|
break; |
||||||
|
} |
||||||
|
li=op_current_link(of); |
||||||
|
if(li!=prev_li){ |
||||||
|
const OpusHead *head; |
||||||
|
const OpusTags *tags; |
||||||
|
int binary_suffix_len; |
||||||
|
int ci; |
||||||
|
/*We found a new link.
|
||||||
|
Print out some information.*/ |
||||||
|
fprintf(stderr,"Decoding link %i: \n",li); |
||||||
|
head=op_head(of,li); |
||||||
|
fprintf(stderr," Channels: %i\n",head->channel_count); |
||||||
|
if(op_seekable(of)){ |
||||||
|
ogg_int64_t duration; |
||||||
|
opus_int64 size; |
||||||
|
duration=op_pcm_total(of,li); |
||||||
|
fprintf(stderr," Duration: "); |
||||||
|
print_duration(stderr,duration,3); |
||||||
|
fprintf(stderr," (%li samples @ 48 kHz)\n",(long)duration); |
||||||
|
size=op_raw_total(of,li); |
||||||
|
fprintf(stderr," Size: "); |
||||||
|
print_size(stderr,size,0,""); |
||||||
|
fprintf(stderr,"\n"); |
||||||
|
} |
||||||
|
if(head->input_sample_rate){ |
||||||
|
fprintf(stderr," Original sampling rate: %lu Hz\n", |
||||||
|
(unsigned long)head->input_sample_rate); |
||||||
|
} |
||||||
|
tags=op_tags(of,li); |
||||||
|
fprintf(stderr," Encoded by: %s\n",tags->vendor); |
||||||
|
for(ci=0;ci<tags->comments;ci++){ |
||||||
|
const char *comment; |
||||||
|
comment=tags->user_comments[ci]; |
||||||
|
if(opus_tagncompare("METADATA_BLOCK_PICTURE",22,comment)==0){ |
||||||
|
OpusPictureTag pic; |
||||||
|
int err; |
||||||
|
err=opus_picture_tag_parse(&pic,comment); |
||||||
|
fprintf(stderr," %.23s",comment); |
||||||
|
if(err>=0){ |
||||||
|
fprintf(stderr,"%u|%s|%s|%ux%ux%u",pic.type,pic.mime_type, |
||||||
|
pic.description,pic.width,pic.height,pic.depth); |
||||||
|
if(pic.colors!=0)fprintf(stderr,"/%u",pic.colors); |
||||||
|
if(pic.format==OP_PIC_FORMAT_URL){ |
||||||
|
fprintf(stderr,"|%s\n",pic.data); |
||||||
|
} |
||||||
|
else{ |
||||||
|
fprintf(stderr,"|<%u bytes of image data>\n",pic.data_length); |
||||||
|
} |
||||||
|
opus_picture_tag_clear(&pic); |
||||||
|
} |
||||||
|
else fprintf(stderr,"<error parsing picture tag>\n"); |
||||||
|
} |
||||||
|
else fprintf(stderr," %s\n",tags->user_comments[ci]); |
||||||
|
} |
||||||
|
if(opus_tags_get_binary_suffix(tags,&binary_suffix_len)!=NULL){ |
||||||
|
fprintf(stderr,"<%u bytes of unknown binary metadata>\n", |
||||||
|
binary_suffix_len); |
||||||
|
} |
||||||
|
fprintf(stderr,"\n"); |
||||||
|
if(!op_seekable(of)){ |
||||||
|
pcm_offset=op_pcm_tell(of)-ret; |
||||||
|
if(pcm_offset!=0){ |
||||||
|
fprintf(stderr,"Non-zero starting PCM offset in link %i: %li\n", |
||||||
|
li,(long)pcm_offset); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if(li!=prev_li||pcm_offset>=pcm_print_offset+48000){ |
||||||
|
opus_int32 next_bitrate; |
||||||
|
opus_int64 raw_offset; |
||||||
|
next_bitrate=op_bitrate_instant(of); |
||||||
|
if(next_bitrate>=0)bitrate=next_bitrate; |
||||||
|
raw_offset=op_raw_tell(of); |
||||||
|
fprintf(stderr,"\r "); |
||||||
|
print_size(stderr,raw_offset,0,""); |
||||||
|
fprintf(stderr," "); |
||||||
|
print_duration(stderr,pcm_offset,0); |
||||||
|
fprintf(stderr," ("); |
||||||
|
print_size(stderr,bitrate,1," "); |
||||||
|
fprintf(stderr,"bps) \r"); |
||||||
|
pcm_print_offset=pcm_offset; |
||||||
|
fflush(stderr); |
||||||
|
} |
||||||
|
next_pcm_offset=op_pcm_tell(of); |
||||||
|
if(pcm_offset+ret!=next_pcm_offset){ |
||||||
|
fprintf(stderr,"\nPCM offset gap! %li+%i!=%li\n", |
||||||
|
(long)pcm_offset,ret,(long)next_pcm_offset); |
||||||
|
} |
||||||
|
pcm_offset=next_pcm_offset; |
||||||
|
if(ret<=0){ |
||||||
|
ret=EXIT_SUCCESS; |
||||||
|
break; |
||||||
|
} |
||||||
|
/*Ensure the data is little-endian before writing it out.*/ |
||||||
|
for(si=0;si<2*ret;si++){ |
||||||
|
out[2*si+0]=(unsigned char)(pcm[si]&0xFF); |
||||||
|
out[2*si+1]=(unsigned char)(pcm[si]>>8&0xFF); |
||||||
|
} |
||||||
|
if(!fwrite(out,sizeof(*out)*4*ret,1,stdout)){ |
||||||
|
fprintf(stderr,"\nError writing decoded audio data: %s\n", |
||||||
|
strerror(errno)); |
||||||
|
ret=EXIT_FAILURE; |
||||||
|
break; |
||||||
|
} |
||||||
|
nsamples+=ret; |
||||||
|
prev_li=li; |
||||||
|
} |
||||||
|
if(ret==EXIT_SUCCESS){ |
||||||
|
fprintf(stderr,"\nDone: played "); |
||||||
|
print_duration(stderr,nsamples,3); |
||||||
|
fprintf(stderr," (%li samples @ 48 kHz).\n",(long)nsamples); |
||||||
|
} |
||||||
|
if(op_seekable(of)&&nsamples!=duration){ |
||||||
|
fprintf(stderr,"\nWARNING: " |
||||||
|
"Number of output samples does not match declared file duration.\n"); |
||||||
|
if(!output_seekable)fprintf(stderr,"Output WAV file will be corrupt.\n"); |
||||||
|
} |
||||||
|
if(output_seekable&&nsamples!=duration){ |
||||||
|
make_wav_header(wav_header,nsamples); |
||||||
|
if(fseek(stdout,0,SEEK_SET)|| |
||||||
|
!fwrite(wav_header,sizeof(wav_header),1,stdout)){ |
||||||
|
fprintf(stderr,"Error rewriting WAV header: %s\n",strerror(errno)); |
||||||
|
ret=EXIT_FAILURE; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
op_free(of); |
||||||
|
return ret; |
||||||
|
} |
@ -0,0 +1,465 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H |
||||||
|
#include "config.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
/*For fileno()*/ |
||||||
|
#if !defined(_POSIX_SOURCE) |
||||||
|
# define _POSIX_SOURCE 1 |
||||||
|
#endif |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <errno.h> |
||||||
|
#include <math.h> |
||||||
|
#include <string.h> |
||||||
|
#include <opusfile.h> |
||||||
|
#if defined(_WIN32) |
||||||
|
# include "win32utf8.h" |
||||||
|
# undef fileno |
||||||
|
# define fileno _fileno |
||||||
|
#endif |
||||||
|
|
||||||
|
/*Use shorts, they're smaller.*/ |
||||||
|
#if !defined(OP_FIXED_POINT) |
||||||
|
# define OP_FIXED_POINT (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(OP_FIXED_POINT) |
||||||
|
|
||||||
|
typedef opus_int16 op_sample; |
||||||
|
|
||||||
|
# define op_read_native op_read |
||||||
|
|
||||||
|
/*TODO: The convergence after 80 ms of preroll is far from exact.
|
||||||
|
Our comparison is very rough. |
||||||
|
Need to find some way to do this better.*/ |
||||||
|
# define MATCH_TOL (16384) |
||||||
|
|
||||||
|
# define ABS(_x) ((_x)<0?-(_x):(_x)) |
||||||
|
|
||||||
|
# define MATCH(_a,_b) (ABS((_a)-(_b))<MATCH_TOL) |
||||||
|
|
||||||
|
/*Don't have fixed-point downmixing code.*/ |
||||||
|
# undef OP_WRITE_SEEK_SAMPLES |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
typedef float op_sample; |
||||||
|
|
||||||
|
# define op_read_native op_read_float |
||||||
|
|
||||||
|
/*TODO: The convergence after 80 ms of preroll is far from exact.
|
||||||
|
Our comparison is very rough. |
||||||
|
Need to find some way to do this better.*/ |
||||||
|
# define MATCH_TOL (16384.0/32768) |
||||||
|
|
||||||
|
# define FABS(_x) ((_x)<0?-(_x):(_x)) |
||||||
|
|
||||||
|
# define MATCH(_a,_b) (FABS((_a)-(_b))<MATCH_TOL) |
||||||
|
|
||||||
|
# if defined(OP_WRITE_SEEK_SAMPLES) |
||||||
|
/*Matrices for downmixing from the supported channel counts to stereo.*/ |
||||||
|
static const float DOWNMIX_MATRIX[8][8][2]={ |
||||||
|
/*mono*/ |
||||||
|
{ |
||||||
|
{1.F,1.F} |
||||||
|
}, |
||||||
|
/*stereo*/ |
||||||
|
{ |
||||||
|
{1.F,0.F},{0.F,1.F} |
||||||
|
}, |
||||||
|
/*3.0*/ |
||||||
|
{ |
||||||
|
{0.5858F,0.F},{0.4142F,0.4142F},{0,0.5858F} |
||||||
|
}, |
||||||
|
/*quadrophonic*/ |
||||||
|
{ |
||||||
|
{0.4226F,0.F},{0,0.4226F},{0.366F,0.2114F},{0.2114F,0.336F} |
||||||
|
}, |
||||||
|
/*5.0*/ |
||||||
|
{ |
||||||
|
{0.651F,0.F},{0.46F,0.46F},{0,0.651F},{0.5636F,0.3254F},{0.3254F,0.5636F} |
||||||
|
}, |
||||||
|
/*5.1*/ |
||||||
|
{ |
||||||
|
{0.529F,0.F},{0.3741F,0.3741F},{0.F,0.529F},{0.4582F,0.2645F}, |
||||||
|
{0.2645F,0.4582F},{0.3741F,0.3741F} |
||||||
|
}, |
||||||
|
/*6.1*/ |
||||||
|
{ |
||||||
|
{0.4553F,0.F},{0.322F,0.322F},{0.F,0.4553F},{0.3943F,0.2277F}, |
||||||
|
{0.2277F,0.3943F},{0.2788F,0.2788F},{0.322F,0.322F} |
||||||
|
}, |
||||||
|
/*7.1*/ |
||||||
|
{ |
||||||
|
{0.3886F,0.F},{0.2748F,0.2748F},{0.F,0.3886F},{0.3366F,0.1943F}, |
||||||
|
{0.1943F,0.3366F},{0.3366F,0.1943F},{0.1943F,0.3366F},{0.2748F,0.2748F} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
static void write_samples(float *_samples,int _nsamples,int _nchannels){ |
||||||
|
float stereo_pcm[120*48*2]; |
||||||
|
int i; |
||||||
|
for(i=0;i<_nsamples;i++){ |
||||||
|
float l; |
||||||
|
float r; |
||||||
|
int ci; |
||||||
|
l=r=0.F; |
||||||
|
for(ci=0;ci<_nchannels;ci++){ |
||||||
|
l+=DOWNMIX_MATRIX[_nchannels-1][ci][0]*_samples[i*_nchannels+ci]; |
||||||
|
r+=DOWNMIX_MATRIX[_nchannels-1][ci][1]*_samples[i*_nchannels+ci]; |
||||||
|
} |
||||||
|
stereo_pcm[2*i+0]=l; |
||||||
|
stereo_pcm[2*i+1]=r; |
||||||
|
} |
||||||
|
fwrite(stereo_pcm,sizeof(*stereo_pcm)*2,_nsamples,stdout); |
||||||
|
} |
||||||
|
# endif |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
static long nfailures; |
||||||
|
|
||||||
|
static void verify_seek(OggOpusFile *_of,opus_int64 _byte_offset, |
||||||
|
ogg_int64_t _pcm_offset,ogg_int64_t _pcm_length,op_sample *_bigassbuffer){ |
||||||
|
opus_int64 byte_offset; |
||||||
|
ogg_int64_t pcm_offset; |
||||||
|
ogg_int64_t duration; |
||||||
|
op_sample buffer[120*48*8]; |
||||||
|
int nchannels; |
||||||
|
int nsamples; |
||||||
|
int li; |
||||||
|
int lj; |
||||||
|
int i; |
||||||
|
byte_offset=op_raw_tell(_of); |
||||||
|
if(_byte_offset!=-1&&byte_offset<_byte_offset){ |
||||||
|
fprintf(stderr,"\nRaw position out of tolerance: requested %li, " |
||||||
|
"got %li.\n",(long)_byte_offset,(long)byte_offset); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
pcm_offset=op_pcm_tell(_of); |
||||||
|
if(_pcm_offset!=-1&&pcm_offset>_pcm_offset){ |
||||||
|
fprintf(stderr,"\nPCM position out of tolerance: requested %li, " |
||||||
|
"got %li.\n",(long)_pcm_offset,(long)pcm_offset); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
if(pcm_offset<0||pcm_offset>_pcm_length){ |
||||||
|
fprintf(stderr,"\nPCM position out of bounds: got %li.\n", |
||||||
|
(long)pcm_offset); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
nsamples=op_read_native(_of,buffer,sizeof(buffer)/sizeof(*buffer),&li); |
||||||
|
if(nsamples<0){ |
||||||
|
fprintf(stderr,"\nFailed to read PCM data after seek: %i\n",nsamples); |
||||||
|
nfailures++; |
||||||
|
li=op_current_link(_of); |
||||||
|
} |
||||||
|
for(lj=0;lj<li;lj++){ |
||||||
|
duration=op_pcm_total(_of,lj); |
||||||
|
if(0<=pcm_offset&&pcm_offset<duration){ |
||||||
|
fprintf(stderr,"\nPCM data after seek came from the wrong link: " |
||||||
|
"expected %i, got %i.\n",lj,li); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
pcm_offset-=duration; |
||||||
|
if(_bigassbuffer!=NULL)_bigassbuffer+=op_channel_count(_of,lj)*duration; |
||||||
|
} |
||||||
|
duration=op_pcm_total(_of,li); |
||||||
|
if(pcm_offset+nsamples>duration){ |
||||||
|
fprintf(stderr,"\nPCM data after seek exceeded link duration: " |
||||||
|
"limit %li, got %li.\n",(long)duration,(long)(pcm_offset+nsamples)); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
nchannels=op_channel_count(_of,li); |
||||||
|
if(_bigassbuffer!=NULL){ |
||||||
|
for(i=0;i<nsamples*nchannels;i++){ |
||||||
|
if(!MATCH(buffer[i],_bigassbuffer[pcm_offset*nchannels+i])){ |
||||||
|
ogg_int64_t j; |
||||||
|
fprintf(stderr,"\nData after seek doesn't match declared PCM " |
||||||
|
"position: mismatch %G\n", |
||||||
|
(double)buffer[i]-_bigassbuffer[pcm_offset*nchannels+i]); |
||||||
|
for(j=0;j<duration-nsamples;j++){ |
||||||
|
for(i=0;i<nsamples*nchannels;i++){ |
||||||
|
if(!MATCH(buffer[i],_bigassbuffer[j*nchannels+i]))break; |
||||||
|
} |
||||||
|
if(i==nsamples*nchannels){ |
||||||
|
fprintf(stderr,"\nData after seek appears to match position %li.\n", |
||||||
|
(long)i); |
||||||
|
} |
||||||
|
} |
||||||
|
nfailures++; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
#if defined(OP_WRITE_SEEK_SAMPLES) |
||||||
|
write_samples(buffer,nsamples,nchannels); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#define OP_MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) |
||||||
|
|
||||||
|
/*A simple wrapper that lets us count the number of underlying seek calls.*/ |
||||||
|
|
||||||
|
static op_seek_func real_seek; |
||||||
|
|
||||||
|
static long nreal_seeks; |
||||||
|
|
||||||
|
static int seek_stat_counter(void *_stream,opus_int64 _offset,int _whence){ |
||||||
|
if(_whence==SEEK_SET)nreal_seeks++; |
||||||
|
/*SEEK_CUR with an offset of 0 is free, as is SEEK_END with an offset of 0
|
||||||
|
(assuming we know the file size), so don't count them.*/ |
||||||
|
else if(_offset!=0)nreal_seeks++; |
||||||
|
return (*real_seek)(_stream,_offset,_whence); |
||||||
|
} |
||||||
|
|
||||||
|
#define NSEEK_TESTS (1000) |
||||||
|
|
||||||
|
static void print_duration(FILE *_fp,ogg_int64_t _nsamples){ |
||||||
|
ogg_int64_t seconds; |
||||||
|
ogg_int64_t minutes; |
||||||
|
ogg_int64_t hours; |
||||||
|
ogg_int64_t days; |
||||||
|
ogg_int64_t weeks; |
||||||
|
seconds=_nsamples/48000; |
||||||
|
_nsamples-=seconds*48000; |
||||||
|
minutes=seconds/60; |
||||||
|
seconds-=minutes*60; |
||||||
|
hours=minutes/60; |
||||||
|
minutes-=hours*60; |
||||||
|
days=hours/24; |
||||||
|
hours-=days*24; |
||||||
|
weeks=days/7; |
||||||
|
days-=weeks*7; |
||||||
|
if(weeks)fprintf(_fp,"%liw",(long)weeks); |
||||||
|
if(weeks||days)fprintf(_fp,"%id",(int)days); |
||||||
|
if(weeks||days||hours){ |
||||||
|
if(weeks||days)fprintf(_fp,"%02ih",(int)hours); |
||||||
|
else fprintf(_fp,"%ih",(int)hours); |
||||||
|
} |
||||||
|
if(weeks||days||hours||minutes){ |
||||||
|
if(weeks||days||hours)fprintf(_fp,"%02im",(int)minutes); |
||||||
|
else fprintf(_fp,"%im",(int)minutes); |
||||||
|
fprintf(_fp,"%02i",(int)seconds); |
||||||
|
} |
||||||
|
else fprintf(_fp,"%i",(int)seconds); |
||||||
|
fprintf(_fp,".%03is",(int)(_nsamples+24)/48); |
||||||
|
} |
||||||
|
|
||||||
|
int main(int _argc,const char **_argv){ |
||||||
|
OpusFileCallbacks cb; |
||||||
|
OggOpusFile *of; |
||||||
|
void *fp; |
||||||
|
#if defined(_WIN32) |
||||||
|
win32_utf8_setup(&_argc,&_argv); |
||||||
|
#endif |
||||||
|
if(_argc!=2){ |
||||||
|
fprintf(stderr,"Usage: %s <file.opus>\n",_argv[0]); |
||||||
|
return EXIT_FAILURE; |
||||||
|
} |
||||||
|
memset(&cb,0,sizeof(cb)); |
||||||
|
if(strcmp(_argv[1],"-")==0)fp=op_fdopen(&cb,fileno(stdin),"rb"); |
||||||
|
else{ |
||||||
|
/*Try to treat the argument as a URL.*/ |
||||||
|
fp=op_url_stream_create(&cb,_argv[1], |
||||||
|
OP_SSL_SKIP_CERTIFICATE_CHECK(1),NULL); |
||||||
|
/*Fall back assuming it's a regular file name.*/ |
||||||
|
if(fp==NULL)fp=op_fopen(&cb,_argv[1],"rb"); |
||||||
|
} |
||||||
|
if(cb.seek!=NULL){ |
||||||
|
real_seek=cb.seek; |
||||||
|
cb.seek=seek_stat_counter; |
||||||
|
} |
||||||
|
of=op_open_callbacks(fp,&cb,NULL,0,NULL); |
||||||
|
if(of==NULL){ |
||||||
|
fprintf(stderr,"Failed to open file '%s'.\n",_argv[1]); |
||||||
|
return EXIT_FAILURE; |
||||||
|
} |
||||||
|
if(op_seekable(of)){ |
||||||
|
op_sample *bigassbuffer; |
||||||
|
ogg_int64_t size; |
||||||
|
ogg_int64_t pcm_offset; |
||||||
|
ogg_int64_t pcm_length; |
||||||
|
ogg_int64_t nsamples; |
||||||
|
long max_seeks; |
||||||
|
int nlinks; |
||||||
|
int ret; |
||||||
|
int li; |
||||||
|
int i; |
||||||
|
/*Because we want to do sample-level verification that the seek does what
|
||||||
|
it claimed, decode the entire file into memory.*/ |
||||||
|
nlinks=op_link_count(of); |
||||||
|
fprintf(stderr,"Opened file containing %i links with %li seeks " |
||||||
|
"(%0.3f per link).\n",nlinks,nreal_seeks,nreal_seeks/(double)nlinks); |
||||||
|
/*Reset the seek counter.*/ |
||||||
|
nreal_seeks=0; |
||||||
|
nsamples=0; |
||||||
|
for(li=0;li<nlinks;li++){ |
||||||
|
nsamples+=op_pcm_total(of,li)*op_channel_count(of,li); |
||||||
|
} |
||||||
|
/*Until we find another way to do the comparisons that solves the MATCH_TOL
|
||||||
|
problem, disable this.*/ |
||||||
|
#if 0 |
||||||
|
bigassbuffer=_ogg_malloc(sizeof(*bigassbuffer)*nsamples); |
||||||
|
if(bigassbuffer==NULL){ |
||||||
|
fprintf(stderr, |
||||||
|
"Buffer allocation failed. Seek offset detection disabled.\n"); |
||||||
|
} |
||||||
|
#else |
||||||
|
bigassbuffer=NULL; |
||||||
|
#endif |
||||||
|
pcm_offset=op_pcm_tell(of); |
||||||
|
if(pcm_offset!=0){ |
||||||
|
fprintf(stderr,"Initial PCM offset was not 0, got %li instead.!\n", |
||||||
|
(long)pcm_offset); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
/*Disabling the linear scan for now.
|
||||||
|
Only test on non-borken files!*/ |
||||||
|
#if 0 |
||||||
|
{ |
||||||
|
op_sample smallerbuffer[120*48*8]; |
||||||
|
ogg_int64_t pcm_print_offset; |
||||||
|
ogg_int64_t si; |
||||||
|
opus_int32 bitrate; |
||||||
|
int saw_hole; |
||||||
|
pcm_print_offset=pcm_offset-48000; |
||||||
|
bitrate=0; |
||||||
|
saw_hole=0; |
||||||
|
for(si=0;si<nsamples;){ |
||||||
|
ogg_int64_t next_pcm_offset; |
||||||
|
opus_int32 next_bitrate; |
||||||
|
op_sample *buf; |
||||||
|
int buf_size; |
||||||
|
buf=bigassbuffer==NULL?smallerbuffer:bigassbuffer+si; |
||||||
|
buf_size=(int)OP_MIN(nsamples-si, |
||||||
|
(int)(sizeof(smallerbuffer)/sizeof(*smallerbuffer))), |
||||||
|
ret=op_read_native(of,buf,buf_size,&li); |
||||||
|
if(ret==OP_HOLE){ |
||||||
|
/*Only warn once in a row.*/ |
||||||
|
if(saw_hole)continue; |
||||||
|
saw_hole=1; |
||||||
|
/*This is just a warning.
|
||||||
|
As long as the timestamps are still contiguous we're okay.*/ |
||||||
|
fprintf(stderr,"\nHole in PCM data at sample %li\n", |
||||||
|
(long)pcm_offset); |
||||||
|
continue; |
||||||
|
} |
||||||
|
else if(ret<=0){ |
||||||
|
fprintf(stderr,"\nFailed to read PCM data: %i\n",ret); |
||||||
|
exit(EXIT_FAILURE); |
||||||
|
} |
||||||
|
saw_hole=0; |
||||||
|
/*If we have gaps in the PCM positions, seeking is not likely to work
|
||||||
|
near them.*/ |
||||||
|
next_pcm_offset=op_pcm_tell(of); |
||||||
|
if(pcm_offset+ret!=next_pcm_offset){ |
||||||
|
fprintf(stderr,"\nGap in PCM offset: expecting %li, got %li\n", |
||||||
|
(long)(pcm_offset+ret),(long)next_pcm_offset); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
pcm_offset=next_pcm_offset; |
||||||
|
si+=ret*op_channel_count(of,li); |
||||||
|
if(pcm_offset>=pcm_print_offset+48000){ |
||||||
|
next_bitrate=op_bitrate_instant(of); |
||||||
|
if(next_bitrate>=0)bitrate=next_bitrate; |
||||||
|
fprintf(stderr,"\r%s... [%li left] (%0.3f kbps) ", |
||||||
|
bigassbuffer==NULL?"Scanning":"Loading",nsamples-si,bitrate/1000.0); |
||||||
|
pcm_print_offset=pcm_offset; |
||||||
|
} |
||||||
|
} |
||||||
|
ret=op_read_native(of,smallerbuffer,8,&li); |
||||||
|
if(ret<0){ |
||||||
|
fprintf(stderr,"Failed to read PCM data: %i\n",ret); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
if(ret>0){ |
||||||
|
fprintf(stderr,"Read too much PCM data!\n"); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
pcm_length=op_pcm_total(of,-1); |
||||||
|
size=op_raw_total(of,-1); |
||||||
|
fprintf(stderr,"\rLoaded (%0.3f kbps average). \n", |
||||||
|
op_bitrate(of,-1)/1000.0); |
||||||
|
fprintf(stderr,"Testing raw seeking to random places in %li bytes...\n", |
||||||
|
(long)size); |
||||||
|
max_seeks=0; |
||||||
|
for(i=0;i<NSEEK_TESTS;i++){ |
||||||
|
long nseeks_tmp; |
||||||
|
opus_int64 byte_offset; |
||||||
|
nseeks_tmp=nreal_seeks; |
||||||
|
byte_offset=(opus_int64)(rand()/(double)RAND_MAX*size); |
||||||
|
fprintf(stderr,"\r\t%3i [raw position %li]... ", |
||||||
|
i,(long)byte_offset); |
||||||
|
ret=op_raw_seek(of,byte_offset); |
||||||
|
if(ret<0){ |
||||||
|
fprintf(stderr,"\nSeek failed: %i.\n",ret); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
if(i==28){ |
||||||
|
i=28; |
||||||
|
} |
||||||
|
verify_seek(of,byte_offset,-1,pcm_length,bigassbuffer); |
||||||
|
nseeks_tmp=nreal_seeks-nseeks_tmp; |
||||||
|
max_seeks=nseeks_tmp>max_seeks?nseeks_tmp:max_seeks; |
||||||
|
} |
||||||
|
fprintf(stderr,"\rTotal seek operations: %li (%.3f per raw seek, %li maximum).\n", |
||||||
|
nreal_seeks,nreal_seeks/(double)NSEEK_TESTS,max_seeks); |
||||||
|
nreal_seeks=0; |
||||||
|
fprintf(stderr,"Testing exact PCM seeking to random places in %li " |
||||||
|
"samples (",(long)pcm_length); |
||||||
|
print_duration(stderr,pcm_length); |
||||||
|
fprintf(stderr,")...\n"); |
||||||
|
max_seeks=0; |
||||||
|
for(i=0;i<NSEEK_TESTS;i++){ |
||||||
|
ogg_int64_t pcm_offset2; |
||||||
|
long nseeks_tmp; |
||||||
|
nseeks_tmp=nreal_seeks; |
||||||
|
pcm_offset=(ogg_int64_t)(rand()/(double)RAND_MAX*pcm_length); |
||||||
|
fprintf(stderr,"\r\t%3i [PCM position %li]... ", |
||||||
|
i,(long)pcm_offset); |
||||||
|
ret=op_pcm_seek(of,pcm_offset); |
||||||
|
if(ret<0){ |
||||||
|
fprintf(stderr,"\nSeek failed: %i.\n",ret); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
pcm_offset2=op_pcm_tell(of); |
||||||
|
if(pcm_offset!=pcm_offset2){ |
||||||
|
fprintf(stderr,"\nDeclared PCM position did not perfectly match " |
||||||
|
"request: requested %li, got %li.\n", |
||||||
|
(long)pcm_offset,(long)pcm_offset2); |
||||||
|
nfailures++; |
||||||
|
} |
||||||
|
verify_seek(of,-1,pcm_offset,pcm_length,bigassbuffer); |
||||||
|
nseeks_tmp=nreal_seeks-nseeks_tmp; |
||||||
|
max_seeks=nseeks_tmp>max_seeks?nseeks_tmp:max_seeks; |
||||||
|
} |
||||||
|
fprintf(stderr,"\rTotal seek operations: %li (%.3f per exact seek, %li maximum).\n", |
||||||
|
nreal_seeks,nreal_seeks/(double)NSEEK_TESTS,max_seeks); |
||||||
|
nreal_seeks=0; |
||||||
|
fprintf(stderr,"OK.\n"); |
||||||
|
_ogg_free(bigassbuffer); |
||||||
|
} |
||||||
|
else{ |
||||||
|
fprintf(stderr,"Input was not seekable.\n"); |
||||||
|
exit(EXIT_FAILURE); |
||||||
|
} |
||||||
|
op_free(of); |
||||||
|
if(nfailures>0){ |
||||||
|
fprintf(stderr,"FAILED: %li failure conditions encountered.\n",nfailures); |
||||||
|
} |
||||||
|
return nfailures!=0?EXIT_FAILURE:EXIT_SUCCESS; |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
|
||||||
|
#if defined(_WIN32) |
||||||
|
# include <stdio.h> |
||||||
|
# include <stdlib.h> |
||||||
|
# include <wchar.h> |
||||||
|
/*We need the following two to set stdin/stdout to binary.*/ |
||||||
|
# include <io.h> |
||||||
|
# include <fcntl.h> |
||||||
|
# define WIN32_LEAN_AND_MEAN |
||||||
|
# define WIN32_EXTRA_LEAN |
||||||
|
# include <windows.h> |
||||||
|
# include "win32utf8.h" |
||||||
|
|
||||||
|
static char *utf16_to_utf8(const wchar_t *_src){ |
||||||
|
char *dst; |
||||||
|
size_t len; |
||||||
|
size_t si; |
||||||
|
size_t di; |
||||||
|
len=wcslen(_src); |
||||||
|
dst=(char *)malloc(sizeof(*dst)*(3*len+1)); |
||||||
|
if(dst==NULL)return dst; |
||||||
|
for(di=si=0;si<len;si++){ |
||||||
|
unsigned c0; |
||||||
|
c0=_src[si]; |
||||||
|
if(c0<0x80){ |
||||||
|
/*Can be represented by a 1-byte sequence.*/ |
||||||
|
dst[di++]=(char)c0; |
||||||
|
continue; |
||||||
|
} |
||||||
|
else if(c0<0x800){ |
||||||
|
/*Can be represented by a 2-byte sequence.*/ |
||||||
|
dst[di++]=(char)(0xC0|c0>>6); |
||||||
|
dst[di++]=(char)(0x80|c0&0x3F); |
||||||
|
continue; |
||||||
|
} |
||||||
|
else if(c0>=0xD800&&c0<0xDC00){ |
||||||
|
unsigned c1; |
||||||
|
/*This is safe, because c0 was not 0 and _src is NUL-terminated.*/ |
||||||
|
c1=_src[si+1]; |
||||||
|
if(c1>=0xDC00&&c1<0xE000){ |
||||||
|
unsigned w; |
||||||
|
/*Surrogate pair.*/ |
||||||
|
w=((c0&0x3FF)<<10|c1&0x3FF)+0x10000; |
||||||
|
/*Can be represented by a 4-byte sequence.*/ |
||||||
|
dst[di++]=(char)(0xF0|w>>18); |
||||||
|
dst[di++]=(char)(0x80|w>>12&0x3F); |
||||||
|
dst[di++]=(char)(0x80|w>>6&0x3F); |
||||||
|
dst[di++]=(char)(0x80|w&0x3F); |
||||||
|
si++; |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
/*Anything else is either a valid 3-byte sequence, an invalid surrogate
|
||||||
|
pair, or 'not a character'. |
||||||
|
In the latter two cases, we just encode the value as a 3-byte |
||||||
|
sequence anyway (producing technically invalid UTF-8). |
||||||
|
Later error handling will detect the problem, with a better |
||||||
|
chance of giving a useful error message.*/ |
||||||
|
dst[di++]=(char)(0xE0|c0>>12); |
||||||
|
dst[di++]=(char)(0x80|c0>>6&0x3F); |
||||||
|
dst[di++]=(char)(0x80|c0&0x3F); |
||||||
|
} |
||||||
|
dst[di++]='\0'; |
||||||
|
return dst; |
||||||
|
} |
||||||
|
|
||||||
|
typedef LPWSTR *(APIENTRY *command_line_to_argv_w_func)(LPCWSTR cmd_line, |
||||||
|
int *num_args); |
||||||
|
|
||||||
|
/*Make a best-effort attempt to support UTF-8 on Windows.*/ |
||||||
|
void win32_utf8_setup(int *_argc,const char ***_argv){ |
||||||
|
HMODULE hlib; |
||||||
|
/*We need to set stdin/stdout to binary mode.
|
||||||
|
This is unrelated to UTF-8 support, but it's platform specific and we need |
||||||
|
to do it in the same places.*/ |
||||||
|
_setmode(_fileno(stdin),_O_BINARY); |
||||||
|
_setmode(_fileno(stdout),_O_BINARY); |
||||||
|
hlib=LoadLibraryA("shell32.dll"); |
||||||
|
if(hlib!=NULL){ |
||||||
|
command_line_to_argv_w_func command_line_to_argv_w; |
||||||
|
/*This function is only available on Windows 2000 or later.*/ |
||||||
|
command_line_to_argv_w=(command_line_to_argv_w_func)GetProcAddress(hlib, |
||||||
|
"CommandLineToArgvW"); |
||||||
|
if(command_line_to_argv_w!=NULL){ |
||||||
|
wchar_t **argvw; |
||||||
|
int argc; |
||||||
|
argvw=(*command_line_to_argv_w)(GetCommandLineW(),&argc); |
||||||
|
if(argvw!=NULL){ |
||||||
|
int ai; |
||||||
|
/*Really, I don't see why argc would ever differ from *_argc, but let's
|
||||||
|
be paranoid.*/ |
||||||
|
if(argc>*_argc)argc=*_argc; |
||||||
|
for(ai=0;ai<argc;ai++){ |
||||||
|
char *argv; |
||||||
|
argv=utf16_to_utf8(argvw[ai]); |
||||||
|
if(argv!=NULL)(*_argv)[ai]=argv; |
||||||
|
} |
||||||
|
*_argc=argc; |
||||||
|
LocalFree(argvw); |
||||||
|
} |
||||||
|
} |
||||||
|
FreeLibrary(hlib); |
||||||
|
} |
||||||
|
# if defined(CP_UTF8) |
||||||
|
/*This does not work correctly in all environments (it breaks output in
|
||||||
|
mingw32 for me), and requires a Unicode font (e.g., when using the default |
||||||
|
Raster font, even characters that are available in the font's codepage |
||||||
|
won't display properly).*/ |
||||||
|
/*SetConsoleOutputCP(CP_UTF8);*/ |
||||||
|
# endif |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,21 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
|
||||||
|
#if !defined(_win32utf8_H) |
||||||
|
# define _win32utf8_H (1) |
||||||
|
# if defined(_WIN32) |
||||||
|
|
||||||
|
/*Make a best-effort attempt to support UTF-8 on Windows.*/ |
||||||
|
void win32_utf8_setup(int *_argc,const char ***_argv); |
||||||
|
|
||||||
|
# endif |
||||||
|
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,529 @@ |
|||||||
|
#!/bin/sh |
||||||
|
# install - install a program, script, or datafile |
||||||
|
|
||||||
|
scriptversion=2018-03-11.20; # UTC |
||||||
|
|
||||||
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was |
||||||
|
# later released in X11R6 (xc/config/util/install.sh) with the |
||||||
|
# following copyright and license. |
||||||
|
# |
||||||
|
# Copyright (C) 1994 X Consortium |
||||||
|
# |
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
# of this software and associated documentation files (the "Software"), to |
||||||
|
# deal in the Software without restriction, including without limitation the |
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
# furnished to do so, subject to the following conditions: |
||||||
|
# |
||||||
|
# The above copyright notice and this permission notice shall be included in |
||||||
|
# all copies or substantial portions of the Software. |
||||||
|
# |
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
||||||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- |
||||||
|
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
# |
||||||
|
# Except as contained in this notice, the name of the X Consortium shall not |
||||||
|
# be used in advertising or otherwise to promote the sale, use or other deal- |
||||||
|
# ings in this Software without prior written authorization from the X Consor- |
||||||
|
# tium. |
||||||
|
# |
||||||
|
# |
||||||
|
# FSF changes to this file are in the public domain. |
||||||
|
# |
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent |
||||||
|
# 'make' implicit rules from creating a file called install from it |
||||||
|
# when there is no Makefile. |
||||||
|
# |
||||||
|
# This script is compatible with the BSD install script, but was written |
||||||
|
# from scratch. |
||||||
|
|
||||||
|
tab=' ' |
||||||
|
nl=' |
||||||
|
' |
||||||
|
IFS=" $tab$nl" |
||||||
|
|
||||||
|
# Set DOITPROG to "echo" to test this script. |
||||||
|
|
||||||
|
doit=${DOITPROG-} |
||||||
|
doit_exec=${doit:-exec} |
||||||
|
|
||||||
|
# Put in absolute file names if you don't have them in your path; |
||||||
|
# or use environment vars. |
||||||
|
|
||||||
|
chgrpprog=${CHGRPPROG-chgrp} |
||||||
|
chmodprog=${CHMODPROG-chmod} |
||||||
|
chownprog=${CHOWNPROG-chown} |
||||||
|
cmpprog=${CMPPROG-cmp} |
||||||
|
cpprog=${CPPROG-cp} |
||||||
|
mkdirprog=${MKDIRPROG-mkdir} |
||||||
|
mvprog=${MVPROG-mv} |
||||||
|
rmprog=${RMPROG-rm} |
||||||
|
stripprog=${STRIPPROG-strip} |
||||||
|
|
||||||
|
posix_mkdir= |
||||||
|
|
||||||
|
# Desired mode of installed file. |
||||||
|
mode=0755 |
||||||
|
|
||||||
|
chgrpcmd= |
||||||
|
chmodcmd=$chmodprog |
||||||
|
chowncmd= |
||||||
|
mvcmd=$mvprog |
||||||
|
rmcmd="$rmprog -f" |
||||||
|
stripcmd= |
||||||
|
|
||||||
|
src= |
||||||
|
dst= |
||||||
|
dir_arg= |
||||||
|
dst_arg= |
||||||
|
|
||||||
|
copy_on_change=false |
||||||
|
is_target_a_directory=possibly |
||||||
|
|
||||||
|
usage="\ |
||||||
|
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE |
||||||
|
or: $0 [OPTION]... SRCFILES... DIRECTORY |
||||||
|
or: $0 [OPTION]... -t DIRECTORY SRCFILES... |
||||||
|
or: $0 [OPTION]... -d DIRECTORIES... |
||||||
|
|
||||||
|
In the 1st form, copy SRCFILE to DSTFILE. |
||||||
|
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. |
||||||
|
In the 4th, create DIRECTORIES. |
||||||
|
|
||||||
|
Options: |
||||||
|
--help display this help and exit. |
||||||
|
--version display version info and exit. |
||||||
|
|
||||||
|
-c (ignored) |
||||||
|
-C install only if different (preserve the last data modification time) |
||||||
|
-d create directories instead of installing files. |
||||||
|
-g GROUP $chgrpprog installed files to GROUP. |
||||||
|
-m MODE $chmodprog installed files to MODE. |
||||||
|
-o USER $chownprog installed files to USER. |
||||||
|
-s $stripprog installed files. |
||||||
|
-t DIRECTORY install into DIRECTORY. |
||||||
|
-T report an error if DSTFILE is a directory. |
||||||
|
|
||||||
|
Environment variables override the default commands: |
||||||
|
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG |
||||||
|
RMPROG STRIPPROG |
||||||
|
" |
||||||
|
|
||||||
|
while test $# -ne 0; do |
||||||
|
case $1 in |
||||||
|
-c) ;; |
||||||
|
|
||||||
|
-C) copy_on_change=true;; |
||||||
|
|
||||||
|
-d) dir_arg=true;; |
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2" |
||||||
|
shift;; |
||||||
|
|
||||||
|
--help) echo "$usage"; exit $?;; |
||||||
|
|
||||||
|
-m) mode=$2 |
||||||
|
case $mode in |
||||||
|
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) |
||||||
|
echo "$0: invalid mode: $mode" >&2 |
||||||
|
exit 1;; |
||||||
|
esac |
||||||
|
shift;; |
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2" |
||||||
|
shift;; |
||||||
|
|
||||||
|
-s) stripcmd=$stripprog;; |
||||||
|
|
||||||
|
-t) |
||||||
|
is_target_a_directory=always |
||||||
|
dst_arg=$2 |
||||||
|
# Protect names problematic for 'test' and other utilities. |
||||||
|
case $dst_arg in |
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;; |
||||||
|
esac |
||||||
|
shift;; |
||||||
|
|
||||||
|
-T) is_target_a_directory=never;; |
||||||
|
|
||||||
|
--version) echo "$0 $scriptversion"; exit $?;; |
||||||
|
|
||||||
|
--) shift |
||||||
|
break;; |
||||||
|
|
||||||
|
-*) echo "$0: invalid option: $1" >&2 |
||||||
|
exit 1;; |
||||||
|
|
||||||
|
*) break;; |
||||||
|
esac |
||||||
|
shift |
||||||
|
done |
||||||
|
|
||||||
|
# We allow the use of options -d and -T together, by making -d |
||||||
|
# take the precedence; this is for compatibility with GNU install. |
||||||
|
|
||||||
|
if test -n "$dir_arg"; then |
||||||
|
if test -n "$dst_arg"; then |
||||||
|
echo "$0: target directory not allowed when installing a directory." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then |
||||||
|
# When -d is used, all remaining arguments are directories to create. |
||||||
|
# When -t is used, the destination is already specified. |
||||||
|
# Otherwise, the last argument is the destination. Remove it from $@. |
||||||
|
for arg |
||||||
|
do |
||||||
|
if test -n "$dst_arg"; then |
||||||
|
# $@ is not empty: it contains at least $arg. |
||||||
|
set fnord "$@" "$dst_arg" |
||||||
|
shift # fnord |
||||||
|
fi |
||||||
|
shift # arg |
||||||
|
dst_arg=$arg |
||||||
|
# Protect names problematic for 'test' and other utilities. |
||||||
|
case $dst_arg in |
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;; |
||||||
|
esac |
||||||
|
done |
||||||
|
fi |
||||||
|
|
||||||
|
if test $# -eq 0; then |
||||||
|
if test -z "$dir_arg"; then |
||||||
|
echo "$0: no input file specified." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
# It's OK to call 'install-sh -d' without argument. |
||||||
|
# This can happen when creating conditional directories. |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
|
||||||
|
if test -z "$dir_arg"; then |
||||||
|
if test $# -gt 1 || test "$is_target_a_directory" = always; then |
||||||
|
if test ! -d "$dst_arg"; then |
||||||
|
echo "$0: $dst_arg: Is not a directory." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
if test -z "$dir_arg"; then |
||||||
|
do_exit='(exit $ret); exit $ret' |
||||||
|
trap "ret=129; $do_exit" 1 |
||||||
|
trap "ret=130; $do_exit" 2 |
||||||
|
trap "ret=141; $do_exit" 13 |
||||||
|
trap "ret=143; $do_exit" 15 |
||||||
|
|
||||||
|
# Set umask so as not to create temps with too-generous modes. |
||||||
|
# However, 'strip' requires both read and write access to temps. |
||||||
|
case $mode in |
||||||
|
# Optimize common cases. |
||||||
|
*644) cp_umask=133;; |
||||||
|
*755) cp_umask=22;; |
||||||
|
|
||||||
|
*[0-7]) |
||||||
|
if test -z "$stripcmd"; then |
||||||
|
u_plus_rw= |
||||||
|
else |
||||||
|
u_plus_rw='% 200' |
||||||
|
fi |
||||||
|
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; |
||||||
|
*) |
||||||
|
if test -z "$stripcmd"; then |
||||||
|
u_plus_rw= |
||||||
|
else |
||||||
|
u_plus_rw=,u+rw |
||||||
|
fi |
||||||
|
cp_umask=$mode$u_plus_rw;; |
||||||
|
esac |
||||||
|
fi |
||||||
|
|
||||||
|
for src |
||||||
|
do |
||||||
|
# Protect names problematic for 'test' and other utilities. |
||||||
|
case $src in |
||||||
|
-* | [=\(\)!]) src=./$src;; |
||||||
|
esac |
||||||
|
|
||||||
|
if test -n "$dir_arg"; then |
||||||
|
dst=$src |
||||||
|
dstdir=$dst |
||||||
|
test -d "$dstdir" |
||||||
|
dstdir_status=$? |
||||||
|
else |
||||||
|
|
||||||
|
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command |
||||||
|
# might cause directories to be created, which would be especially bad |
||||||
|
# if $src (and thus $dsttmp) contains '*'. |
||||||
|
if test ! -f "$src" && test ! -d "$src"; then |
||||||
|
echo "$0: $src does not exist." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
if test -z "$dst_arg"; then |
||||||
|
echo "$0: no destination specified." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
dst=$dst_arg |
||||||
|
|
||||||
|
# If destination is a directory, append the input filename. |
||||||
|
if test -d "$dst"; then |
||||||
|
if test "$is_target_a_directory" = never; then |
||||||
|
echo "$0: $dst_arg: Is a directory" >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
dstdir=$dst |
||||||
|
dstbase=`basename "$src"` |
||||||
|
case $dst in |
||||||
|
*/) dst=$dst$dstbase;; |
||||||
|
*) dst=$dst/$dstbase;; |
||||||
|
esac |
||||||
|
dstdir_status=0 |
||||||
|
else |
||||||
|
dstdir=`dirname "$dst"` |
||||||
|
test -d "$dstdir" |
||||||
|
dstdir_status=$? |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
case $dstdir in |
||||||
|
*/) dstdirslash=$dstdir;; |
||||||
|
*) dstdirslash=$dstdir/;; |
||||||
|
esac |
||||||
|
|
||||||
|
obsolete_mkdir_used=false |
||||||
|
|
||||||
|
if test $dstdir_status != 0; then |
||||||
|
case $posix_mkdir in |
||||||
|
'') |
||||||
|
# Create intermediate dirs using mode 755 as modified by the umask. |
||||||
|
# This is like FreeBSD 'install' as of 1997-10-28. |
||||||
|
umask=`umask` |
||||||
|
case $stripcmd.$umask in |
||||||
|
# Optimize common cases. |
||||||
|
*[2367][2367]) mkdir_umask=$umask;; |
||||||
|
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; |
||||||
|
|
||||||
|
*[0-7]) |
||||||
|
mkdir_umask=`expr $umask + 22 \ |
||||||
|
- $umask % 100 % 40 + $umask % 20 \ |
||||||
|
- $umask % 10 % 4 + $umask % 2 |
||||||
|
`;; |
||||||
|
*) mkdir_umask=$umask,go-w;; |
||||||
|
esac |
||||||
|
|
||||||
|
# With -d, create the new directory with the user-specified mode. |
||||||
|
# Otherwise, rely on $mkdir_umask. |
||||||
|
if test -n "$dir_arg"; then |
||||||
|
mkdir_mode=-m$mode |
||||||
|
else |
||||||
|
mkdir_mode= |
||||||
|
fi |
||||||
|
|
||||||
|
posix_mkdir=false |
||||||
|
case $umask in |
||||||
|
*[123567][0-7][0-7]) |
||||||
|
# POSIX mkdir -p sets u+wx bits regardless of umask, which |
||||||
|
# is incompatible with FreeBSD 'install' when (umask & 300) != 0. |
||||||
|
;; |
||||||
|
*) |
||||||
|
# Note that $RANDOM variable is not portable (e.g. dash); Use it |
||||||
|
# here however when possible just to lower collision chance. |
||||||
|
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ |
||||||
|
|
||||||
|
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 |
||||||
|
|
||||||
|
# Because "mkdir -p" follows existing symlinks and we likely work |
||||||
|
# directly in world-writeable /tmp, make sure that the '$tmpdir' |
||||||
|
# directory is successfully created first before we actually test |
||||||
|
# 'mkdir -p' feature. |
||||||
|
if (umask $mkdir_umask && |
||||||
|
$mkdirprog $mkdir_mode "$tmpdir" && |
||||||
|
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 |
||||||
|
then |
||||||
|
if test -z "$dir_arg" || { |
||||||
|
# Check for POSIX incompatibilities with -m. |
||||||
|
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or |
||||||
|
# other-writable bit of parent directory when it shouldn't. |
||||||
|
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory. |
||||||
|
test_tmpdir="$tmpdir/a" |
||||||
|
ls_ld_tmpdir=`ls -ld "$test_tmpdir"` |
||||||
|
case $ls_ld_tmpdir in |
||||||
|
d????-?r-*) different_mode=700;; |
||||||
|
d????-?--*) different_mode=755;; |
||||||
|
*) false;; |
||||||
|
esac && |
||||||
|
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && { |
||||||
|
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` |
||||||
|
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" |
||||||
|
} |
||||||
|
} |
||||||
|
then posix_mkdir=: |
||||||
|
fi |
||||||
|
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" |
||||||
|
else |
||||||
|
# Remove any dirs left behind by ancient mkdir implementations. |
||||||
|
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null |
||||||
|
fi |
||||||
|
trap '' 0;; |
||||||
|
esac;; |
||||||
|
esac |
||||||
|
|
||||||
|
if |
||||||
|
$posix_mkdir && ( |
||||||
|
umask $mkdir_umask && |
||||||
|
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" |
||||||
|
) |
||||||
|
then : |
||||||
|
else |
||||||
|
|
||||||
|
# The umask is ridiculous, or mkdir does not conform to POSIX, |
||||||
|
# or it failed possibly due to a race condition. Create the |
||||||
|
# directory the slow way, step by step, checking for races as we go. |
||||||
|
|
||||||
|
case $dstdir in |
||||||
|
/*) prefix='/';; |
||||||
|
[-=\(\)!]*) prefix='./';; |
||||||
|
*) prefix='';; |
||||||
|
esac |
||||||
|
|
||||||
|
oIFS=$IFS |
||||||
|
IFS=/ |
||||||
|
set -f |
||||||
|
set fnord $dstdir |
||||||
|
shift |
||||||
|
set +f |
||||||
|
IFS=$oIFS |
||||||
|
|
||||||
|
prefixes= |
||||||
|
|
||||||
|
for d |
||||||
|
do |
||||||
|
test X"$d" = X && continue |
||||||
|
|
||||||
|
prefix=$prefix$d |
||||||
|
if test -d "$prefix"; then |
||||||
|
prefixes= |
||||||
|
else |
||||||
|
if $posix_mkdir; then |
||||||
|
(umask=$mkdir_umask && |
||||||
|
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break |
||||||
|
# Don't fail if two instances are running concurrently. |
||||||
|
test -d "$prefix" || exit 1 |
||||||
|
else |
||||||
|
case $prefix in |
||||||
|
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; |
||||||
|
*) qprefix=$prefix;; |
||||||
|
esac |
||||||
|
prefixes="$prefixes '$qprefix'" |
||||||
|
fi |
||||||
|
fi |
||||||
|
prefix=$prefix/ |
||||||
|
done |
||||||
|
|
||||||
|
if test -n "$prefixes"; then |
||||||
|
# Don't fail if two instances are running concurrently. |
||||||
|
(umask $mkdir_umask && |
||||||
|
eval "\$doit_exec \$mkdirprog $prefixes") || |
||||||
|
test -d "$dstdir" || exit 1 |
||||||
|
obsolete_mkdir_used=true |
||||||
|
fi |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
if test -n "$dir_arg"; then |
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } && |
||||||
|
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && |
||||||
|
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || |
||||||
|
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 |
||||||
|
else |
||||||
|
|
||||||
|
# Make a couple of temp file names in the proper directory. |
||||||
|
dsttmp=${dstdirslash}_inst.$$_ |
||||||
|
rmtmp=${dstdirslash}_rm.$$_ |
||||||
|
|
||||||
|
# Trap to clean up those temp files at exit. |
||||||
|
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 |
||||||
|
|
||||||
|
# Copy the file name to the temp name. |
||||||
|
(umask $cp_umask && |
||||||
|
{ test -z "$stripcmd" || { |
||||||
|
# Create $dsttmp read-write so that cp doesn't create it read-only, |
||||||
|
# which would cause strip to fail. |
||||||
|
if test -z "$doit"; then |
||||||
|
: >"$dsttmp" # No need to fork-exec 'touch'. |
||||||
|
else |
||||||
|
$doit touch "$dsttmp" |
||||||
|
fi |
||||||
|
} |
||||||
|
} && |
||||||
|
$doit_exec $cpprog "$src" "$dsttmp") && |
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits. |
||||||
|
# |
||||||
|
# If any of these fail, we abort the whole thing. If we want to |
||||||
|
# ignore errors from any of these, just make sure not to ignore |
||||||
|
# errors from the above "$doit $cpprog $src $dsttmp" command. |
||||||
|
# |
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && |
||||||
|
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && |
||||||
|
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && |
||||||
|
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && |
||||||
|
|
||||||
|
# If -C, don't bother to copy if it wouldn't change the file. |
||||||
|
if $copy_on_change && |
||||||
|
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && |
||||||
|
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && |
||||||
|
set -f && |
||||||
|
set X $old && old=:$2:$4:$5:$6 && |
||||||
|
set X $new && new=:$2:$4:$5:$6 && |
||||||
|
set +f && |
||||||
|
test "$old" = "$new" && |
||||||
|
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 |
||||||
|
then |
||||||
|
rm -f "$dsttmp" |
||||||
|
else |
||||||
|
# Rename the file to the real destination. |
||||||
|
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || |
||||||
|
|
||||||
|
# The rename failed, perhaps because mv can't rename something else |
||||||
|
# to itself, or perhaps because mv is so ancient that it does not |
||||||
|
# support -f. |
||||||
|
{ |
||||||
|
# Now remove or move aside any old file at destination location. |
||||||
|
# We try this two ways since rm can't unlink itself on some |
||||||
|
# systems and the destination file might be busy for other |
||||||
|
# reasons. In this case, the final cleanup might fail but the new |
||||||
|
# file should still install successfully. |
||||||
|
{ |
||||||
|
test ! -f "$dst" || |
||||||
|
$doit $rmcmd -f "$dst" 2>/dev/null || |
||||||
|
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && |
||||||
|
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } |
||||||
|
} || |
||||||
|
{ echo "$0: cannot unlink or rename $dst" >&2 |
||||||
|
(exit 1); exit 1 |
||||||
|
} |
||||||
|
} && |
||||||
|
|
||||||
|
# Now rename the file to the real destination. |
||||||
|
$doit $mvcmd "$dsttmp" "$dst" |
||||||
|
} |
||||||
|
fi || exit 1 |
||||||
|
|
||||||
|
trap '' 0 |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
# Local variables: |
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp) |
||||||
|
# time-stamp-start: "scriptversion=" |
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H" |
||||||
|
# time-stamp-time-zone: "UTC0" |
||||||
|
# time-stamp-end: "; # UTC" |
||||||
|
# End: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,321 @@ |
|||||||
|
dnl Macros to check the presence of generic (non-typed) symbols. |
||||||
|
dnl Copyright (c) 2006-2007 Diego Pettenò <flameeyes@gmail.com> |
||||||
|
dnl Copyright (c) 2006-2007 xine project |
||||||
|
dnl |
||||||
|
dnl This program is free software; you can redistribute it and/or modify |
||||||
|
dnl it under the terms of the GNU General Public License as published by |
||||||
|
dnl the Free Software Foundation; either version 2, or (at your option) |
||||||
|
dnl any later version. |
||||||
|
dnl |
||||||
|
dnl This program is distributed in the hope that it will be useful, |
||||||
|
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
dnl GNU General Public License for more details. |
||||||
|
dnl |
||||||
|
dnl You should have received a copy of the GNU General Public License |
||||||
|
dnl along with this program; if not, write to the Free Software |
||||||
|
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
||||||
|
dnl 02110-1301, USA. |
||||||
|
dnl |
||||||
|
dnl As a special exception, the copyright owners of the |
||||||
|
dnl macro gives unlimited permission to copy, distribute and modify the |
||||||
|
dnl configure scripts that are the output of Autoconf when processing the |
||||||
|
dnl Macro. You need not follow the terms of the GNU General Public |
||||||
|
dnl License when using or distributing such scripts, even though portions |
||||||
|
dnl of the text of the Macro appear in them. The GNU General Public |
||||||
|
dnl License (GPL) does govern all other use of the material that |
||||||
|
dnl constitutes the Autoconf Macro. |
||||||
|
dnl |
||||||
|
dnl This special exception to the GPL applies to versions of the |
||||||
|
dnl Autoconf Macro released by this project. When you make and |
||||||
|
dnl distribute a modified version of the Autoconf Macro, you may extend |
||||||
|
dnl this special exception to the GPL to apply to your modified version as |
||||||
|
dnl well. |
||||||
|
|
||||||
|
dnl Check if the flag is supported by compiler |
||||||
|
dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ |
||||||
|
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), |
||||||
|
[ac_save_CFLAGS="$CFLAGS" |
||||||
|
CFLAGS="$CFLAGS $1" |
||||||
|
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 0; }])], |
||||||
|
[eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], |
||||||
|
[eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) |
||||||
|
CFLAGS="$ac_save_CFLAGS" |
||||||
|
]) |
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], |
||||||
|
[$2], [$3]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl Check if the flag is supported by compiler (cacheable) |
||||||
|
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_CFLAGS], [ |
||||||
|
AC_CACHE_CHECK([if $CC supports $1 flag], |
||||||
|
AS_TR_SH([cc_cv_cflags_$1]), |
||||||
|
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! |
||||||
|
) |
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], |
||||||
|
[$2], [$3]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) |
||||||
|
dnl Check for CFLAG and appends them to CFLAGS if supported |
||||||
|
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ |
||||||
|
AC_CACHE_CHECK([if $CC supports $1 flag], |
||||||
|
AS_TR_SH([cc_cv_cflags_$1]), |
||||||
|
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! |
||||||
|
) |
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], |
||||||
|
[CFLAGS="$CFLAGS $1"; $2], [$3]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) |
||||||
|
AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ |
||||||
|
for flag in $1; do |
||||||
|
CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) |
||||||
|
done |
||||||
|
]) |
||||||
|
|
||||||
|
dnl Check if the flag is supported by linker (cacheable) |
||||||
|
dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_LDFLAGS], [ |
||||||
|
AC_CACHE_CHECK([if $CC supports $1 flag], |
||||||
|
AS_TR_SH([cc_cv_ldflags_$1]), |
||||||
|
[ac_save_LDFLAGS="$LDFLAGS" |
||||||
|
LDFLAGS="$LDFLAGS $1" |
||||||
|
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], |
||||||
|
[eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], |
||||||
|
[eval "AS_TR_SH([cc_cv_ldflags_$1])="]) |
||||||
|
LDFLAGS="$ac_save_LDFLAGS" |
||||||
|
]) |
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], |
||||||
|
[$2], [$3]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for |
||||||
|
dnl the current linker to avoid undefined references in a shared object. |
||||||
|
AC_DEFUN([CC_NOUNDEFINED], [ |
||||||
|
dnl We check $host for which systems to enable this for. |
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST]) |
||||||
|
|
||||||
|
case $host in |
||||||
|
dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads |
||||||
|
dnl are requested, as different implementations are present; to avoid problems |
||||||
|
dnl use -Wl,-z,defs only for those platform not behaving this way. |
||||||
|
*-freebsd* | *-openbsd*) ;; |
||||||
|
*) |
||||||
|
dnl First of all check for the --no-undefined variant of GNU ld. This allows |
||||||
|
dnl for a much more readable commandline, so that people can understand what |
||||||
|
dnl it does without going to look for what the heck -z defs does. |
||||||
|
for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do |
||||||
|
CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) |
||||||
|
break |
||||||
|
done |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
AC_SUBST([LDFLAGS_NOUNDEFINED]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl Check for a -Werror flag or equivalent. -Werror is the GCC |
||||||
|
dnl and ICC flag that tells the compiler to treat all the warnings |
||||||
|
dnl as fatal. We usually need this option to make sure that some |
||||||
|
dnl constructs (like attributes) are not simply ignored. |
||||||
|
dnl |
||||||
|
dnl Other compilers don't support -Werror per se, but they support |
||||||
|
dnl an equivalent flag: |
||||||
|
dnl - Sun Studio compiler supports -errwarn=%all |
||||||
|
AC_DEFUN([CC_CHECK_WERROR], [ |
||||||
|
AC_CACHE_CHECK( |
||||||
|
[for $CC way to treat warnings as errors], |
||||||
|
[cc_cv_werror], |
||||||
|
[CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], |
||||||
|
[CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) |
||||||
|
]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_ATTRIBUTE], [ |
||||||
|
AC_REQUIRE([CC_CHECK_WERROR]) |
||||||
|
AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], |
||||||
|
AS_TR_SH([cc_cv_attribute_$1]), |
||||||
|
[ac_save_CFLAGS="$CFLAGS" |
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror" |
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], |
||||||
|
[eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], |
||||||
|
[eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) |
||||||
|
CFLAGS="$ac_save_CFLAGS" |
||||||
|
]) |
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], |
||||||
|
[AC_DEFINE( |
||||||
|
AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, |
||||||
|
[Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] |
||||||
|
) |
||||||
|
$4], |
||||||
|
[$5]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[constructor],, |
||||||
|
[extern void foo(); |
||||||
|
void __attribute__((constructor)) ctor() { foo(); }], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_DESTRUCTOR], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[destructor],, |
||||||
|
[extern void foo(); |
||||||
|
void __attribute__((destructor)) dtor() { foo(); }], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[format], [format(printf, n, n)], |
||||||
|
[void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[format_arg], [format_arg(printf)], |
||||||
|
[char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[visibility_$1], [visibility("$1")], |
||||||
|
[void __attribute__((visibility("$1"))) $1_function() { }], |
||||||
|
[$2], [$3]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[nonnull], [nonnull()], |
||||||
|
[void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[unused], , |
||||||
|
[void some_function(void *foo, __attribute__((unused)) void *bar);], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[sentinel], , |
||||||
|
[void some_function(void *foo, ...) __attribute__((sentinel));], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[deprecated], , |
||||||
|
[void some_function(void *foo, ...) __attribute__((deprecated));], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[alias], [weak, alias], |
||||||
|
[void other_function(void *foo) { } |
||||||
|
void some_function(void *foo) __attribute__((weak, alias("other_function")));], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[malloc], , |
||||||
|
[void * __attribute__((malloc)) my_alloc(int n);], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_PACKED], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[packed], , |
||||||
|
[struct astructure { char a; int b; long c; void *d; } __attribute__((packed)); |
||||||
|
char assert@<:@(sizeof(struct astructure) == (sizeof(char)+sizeof(int)+sizeof(long)+sizeof(void*)))-1@:>@;], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_CONST], [ |
||||||
|
CC_CHECK_ATTRIBUTE( |
||||||
|
[const], , |
||||||
|
[int __attribute__((const)) twopow(int n) { return 1 << n; } ], |
||||||
|
[$1], [$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_FLAG_VISIBILITY], [ |
||||||
|
AC_REQUIRE([CC_CHECK_WERROR]) |
||||||
|
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], |
||||||
|
[cc_cv_flag_visibility], |
||||||
|
[cc_flag_visibility_save_CFLAGS="$CFLAGS" |
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror" |
||||||
|
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], |
||||||
|
cc_cv_flag_visibility='yes', |
||||||
|
cc_cv_flag_visibility='no') |
||||||
|
CFLAGS="$cc_flag_visibility_save_CFLAGS"]) |
||||||
|
|
||||||
|
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], |
||||||
|
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, |
||||||
|
[Define this if the compiler supports the -fvisibility flag]) |
||||||
|
$1], |
||||||
|
[$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_FUNC_EXPECT], [ |
||||||
|
AC_REQUIRE([CC_CHECK_WERROR]) |
||||||
|
AC_CACHE_CHECK([if compiler has __builtin_expect function], |
||||||
|
[cc_cv_func_expect], |
||||||
|
[ac_save_CFLAGS="$CFLAGS" |
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror" |
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE( |
||||||
|
[int some_function() { |
||||||
|
int a = 3; |
||||||
|
return (int)__builtin_expect(a, 3); |
||||||
|
}])], |
||||||
|
[cc_cv_func_expect=yes], |
||||||
|
[cc_cv_func_expect=no]) |
||||||
|
CFLAGS="$ac_save_CFLAGS" |
||||||
|
]) |
||||||
|
|
||||||
|
AS_IF([test "x$cc_cv_func_expect" = "xyes"], |
||||||
|
[AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, |
||||||
|
[Define this if the compiler supports __builtin_expect() function]) |
||||||
|
$1], |
||||||
|
[$2]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ |
||||||
|
AC_REQUIRE([CC_CHECK_WERROR]) |
||||||
|
AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], |
||||||
|
[cc_cv_attribute_aligned], |
||||||
|
[ac_save_CFLAGS="$CFLAGS" |
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror" |
||||||
|
for cc_attribute_align_try in 64 32 16 8 4 2; do |
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([ |
||||||
|
int main() { |
||||||
|
static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; |
||||||
|
return c; |
||||||
|
}])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) |
||||||
|
done |
||||||
|
CFLAGS="$ac_save_CFLAGS" |
||||||
|
]) |
||||||
|
|
||||||
|
if test "x$cc_cv_attribute_aligned" != "x"; then |
||||||
|
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], |
||||||
|
[Define the highest alignment supported]) |
||||||
|
fi |
||||||
|
]) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,437 @@ |
|||||||
|
# Helper functions for option handling. -*- Autoconf -*- |
||||||
|
# |
||||||
|
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software |
||||||
|
# Foundation, Inc. |
||||||
|
# Written by Gary V. Vaughan, 2004 |
||||||
|
# |
||||||
|
# This file is free software; the Free Software Foundation gives |
||||||
|
# unlimited permission to copy and/or distribute it, with or without |
||||||
|
# modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
# serial 8 ltoptions.m4 |
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define. |
||||||
|
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) |
||||||
|
# ------------------------------------------ |
||||||
|
m4_define([_LT_MANGLE_OPTION], |
||||||
|
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) |
||||||
|
# --------------------------------------- |
||||||
|
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a |
||||||
|
# matching handler defined, dispatch to it. Other OPTION-NAMEs are |
||||||
|
# saved as a flag. |
||||||
|
m4_define([_LT_SET_OPTION], |
||||||
|
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl |
||||||
|
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), |
||||||
|
_LT_MANGLE_DEFUN([$1], [$2]), |
||||||
|
[m4_warning([Unknown $1 option '$2'])])[]dnl |
||||||
|
]) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) |
||||||
|
# ------------------------------------------------------------ |
||||||
|
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. |
||||||
|
m4_define([_LT_IF_OPTION], |
||||||
|
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) |
||||||
|
# ------------------------------------------------------- |
||||||
|
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME |
||||||
|
# are set. |
||||||
|
m4_define([_LT_UNLESS_OPTIONS], |
||||||
|
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), |
||||||
|
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), |
||||||
|
[m4_define([$0_found])])])[]dnl |
||||||
|
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 |
||||||
|
])[]dnl |
||||||
|
]) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) |
||||||
|
# ---------------------------------------- |
||||||
|
# OPTION-LIST is a space-separated list of Libtool options associated |
||||||
|
# with MACRO-NAME. If any OPTION has a matching handler declared with |
||||||
|
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about |
||||||
|
# the unknown option and exit. |
||||||
|
m4_defun([_LT_SET_OPTIONS], |
||||||
|
[# Set options |
||||||
|
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), |
||||||
|
[_LT_SET_OPTION([$1], _LT_Option)]) |
||||||
|
|
||||||
|
m4_if([$1],[LT_INIT],[ |
||||||
|
dnl |
||||||
|
dnl Simply set some default values (i.e off) if boolean options were not |
||||||
|
dnl specified: |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no |
||||||
|
]) |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no |
||||||
|
]) |
||||||
|
dnl |
||||||
|
dnl If no reference was made to various pairs of opposing options, then |
||||||
|
dnl we run the default mode handler for the pair. For example, if neither |
||||||
|
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared |
||||||
|
dnl archives by default: |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], |
||||||
|
[_LT_ENABLE_FAST_INSTALL]) |
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], |
||||||
|
[_LT_WITH_AIX_SONAME([aix])]) |
||||||
|
]) |
||||||
|
])# _LT_SET_OPTIONS |
||||||
|
|
||||||
|
|
||||||
|
## --------------------------------- ## |
||||||
|
## Macros to handle LT_INIT options. ## |
||||||
|
## --------------------------------- ## |
||||||
|
|
||||||
|
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) |
||||||
|
# ----------------------------------------- |
||||||
|
m4_define([_LT_MANGLE_DEFUN], |
||||||
|
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) |
||||||
|
|
||||||
|
|
||||||
|
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) |
||||||
|
# ----------------------------------------------- |
||||||
|
m4_define([LT_OPTION_DEFINE], |
||||||
|
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl |
||||||
|
])# LT_OPTION_DEFINE |
||||||
|
|
||||||
|
|
||||||
|
# dlopen |
||||||
|
# ------ |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes |
||||||
|
]) |
||||||
|
|
||||||
|
AU_DEFUN([AC_LIBTOOL_DLOPEN], |
||||||
|
[_LT_SET_OPTION([LT_INIT], [dlopen]) |
||||||
|
AC_DIAGNOSE([obsolete], |
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you |
||||||
|
put the 'dlopen' option into LT_INIT's first parameter.]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility: |
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) |
||||||
|
|
||||||
|
|
||||||
|
# win32-dll |
||||||
|
# --------- |
||||||
|
# Declare package support for building win32 dll's. |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [win32-dll], |
||||||
|
[enable_win32_dll=yes |
||||||
|
|
||||||
|
case $host in |
||||||
|
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) |
||||||
|
AC_CHECK_TOOL(AS, as, false) |
||||||
|
AC_CHECK_TOOL(DLLTOOL, dlltool, false) |
||||||
|
AC_CHECK_TOOL(OBJDUMP, objdump, false) |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
test -z "$AS" && AS=as |
||||||
|
_LT_DECL([], [AS], [1], [Assembler program])dnl |
||||||
|
|
||||||
|
test -z "$DLLTOOL" && DLLTOOL=dlltool |
||||||
|
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl |
||||||
|
|
||||||
|
test -z "$OBJDUMP" && OBJDUMP=objdump |
||||||
|
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl |
||||||
|
])# win32-dll |
||||||
|
|
||||||
|
AU_DEFUN([AC_LIBTOOL_WIN32_DLL], |
||||||
|
[AC_REQUIRE([AC_CANONICAL_HOST])dnl |
||||||
|
_LT_SET_OPTION([LT_INIT], [win32-dll]) |
||||||
|
AC_DIAGNOSE([obsolete], |
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you |
||||||
|
put the 'win32-dll' option into LT_INIT's first parameter.]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility: |
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_SHARED([DEFAULT]) |
||||||
|
# ---------------------------- |
||||||
|
# implement the --enable-shared flag, and supports the 'shared' and |
||||||
|
# 'disable-shared' LT_INIT options. |
||||||
|
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. |
||||||
|
m4_define([_LT_ENABLE_SHARED], |
||||||
|
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl |
||||||
|
AC_ARG_ENABLE([shared], |
||||||
|
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], |
||||||
|
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], |
||||||
|
[p=${PACKAGE-default} |
||||||
|
case $enableval in |
||||||
|
yes) enable_shared=yes ;; |
||||||
|
no) enable_shared=no ;; |
||||||
|
*) |
||||||
|
enable_shared=no |
||||||
|
# Look at the argument we got. We use all the common list separators. |
||||||
|
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||||
|
for pkg in $enableval; do |
||||||
|
IFS=$lt_save_ifs |
||||||
|
if test "X$pkg" = "X$p"; then |
||||||
|
enable_shared=yes |
||||||
|
fi |
||||||
|
done |
||||||
|
IFS=$lt_save_ifs |
||||||
|
;; |
||||||
|
esac], |
||||||
|
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT) |
||||||
|
|
||||||
|
_LT_DECL([build_libtool_libs], [enable_shared], [0], |
||||||
|
[Whether or not to build shared libraries]) |
||||||
|
])# _LT_ENABLE_SHARED |
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) |
||||||
|
|
||||||
|
# Old names: |
||||||
|
AC_DEFUN([AC_ENABLE_SHARED], |
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([AC_DISABLE_SHARED], |
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-shared]) |
||||||
|
]) |
||||||
|
|
||||||
|
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) |
||||||
|
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) |
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility: |
||||||
|
dnl AC_DEFUN([AM_ENABLE_SHARED], []) |
||||||
|
dnl AC_DEFUN([AM_DISABLE_SHARED], []) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_STATIC([DEFAULT]) |
||||||
|
# ---------------------------- |
||||||
|
# implement the --enable-static flag, and support the 'static' and |
||||||
|
# 'disable-static' LT_INIT options. |
||||||
|
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. |
||||||
|
m4_define([_LT_ENABLE_STATIC], |
||||||
|
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl |
||||||
|
AC_ARG_ENABLE([static], |
||||||
|
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], |
||||||
|
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], |
||||||
|
[p=${PACKAGE-default} |
||||||
|
case $enableval in |
||||||
|
yes) enable_static=yes ;; |
||||||
|
no) enable_static=no ;; |
||||||
|
*) |
||||||
|
enable_static=no |
||||||
|
# Look at the argument we got. We use all the common list separators. |
||||||
|
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||||
|
for pkg in $enableval; do |
||||||
|
IFS=$lt_save_ifs |
||||||
|
if test "X$pkg" = "X$p"; then |
||||||
|
enable_static=yes |
||||||
|
fi |
||||||
|
done |
||||||
|
IFS=$lt_save_ifs |
||||||
|
;; |
||||||
|
esac], |
||||||
|
[enable_static=]_LT_ENABLE_STATIC_DEFAULT) |
||||||
|
|
||||||
|
_LT_DECL([build_old_libs], [enable_static], [0], |
||||||
|
[Whether or not to build static libraries]) |
||||||
|
])# _LT_ENABLE_STATIC |
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) |
||||||
|
|
||||||
|
# Old names: |
||||||
|
AC_DEFUN([AC_ENABLE_STATIC], |
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([AC_DISABLE_STATIC], |
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-static]) |
||||||
|
]) |
||||||
|
|
||||||
|
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) |
||||||
|
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) |
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility: |
||||||
|
dnl AC_DEFUN([AM_ENABLE_STATIC], []) |
||||||
|
dnl AC_DEFUN([AM_DISABLE_STATIC], []) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_FAST_INSTALL([DEFAULT]) |
||||||
|
# ---------------------------------- |
||||||
|
# implement the --enable-fast-install flag, and support the 'fast-install' |
||||||
|
# and 'disable-fast-install' LT_INIT options. |
||||||
|
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. |
||||||
|
m4_define([_LT_ENABLE_FAST_INSTALL], |
||||||
|
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl |
||||||
|
AC_ARG_ENABLE([fast-install], |
||||||
|
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], |
||||||
|
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], |
||||||
|
[p=${PACKAGE-default} |
||||||
|
case $enableval in |
||||||
|
yes) enable_fast_install=yes ;; |
||||||
|
no) enable_fast_install=no ;; |
||||||
|
*) |
||||||
|
enable_fast_install=no |
||||||
|
# Look at the argument we got. We use all the common list separators. |
||||||
|
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||||
|
for pkg in $enableval; do |
||||||
|
IFS=$lt_save_ifs |
||||||
|
if test "X$pkg" = "X$p"; then |
||||||
|
enable_fast_install=yes |
||||||
|
fi |
||||||
|
done |
||||||
|
IFS=$lt_save_ifs |
||||||
|
;; |
||||||
|
esac], |
||||||
|
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) |
||||||
|
|
||||||
|
_LT_DECL([fast_install], [enable_fast_install], [0], |
||||||
|
[Whether or not to optimize for fast installation])dnl |
||||||
|
])# _LT_ENABLE_FAST_INSTALL |
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) |
||||||
|
|
||||||
|
# Old names: |
||||||
|
AU_DEFUN([AC_ENABLE_FAST_INSTALL], |
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) |
||||||
|
AC_DIAGNOSE([obsolete], |
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you put |
||||||
|
the 'fast-install' option into LT_INIT's first parameter.]) |
||||||
|
]) |
||||||
|
|
||||||
|
AU_DEFUN([AC_DISABLE_FAST_INSTALL], |
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) |
||||||
|
AC_DIAGNOSE([obsolete], |
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you put |
||||||
|
the 'disable-fast-install' option into LT_INIT's first parameter.]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility: |
||||||
|
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) |
||||||
|
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_WITH_AIX_SONAME([DEFAULT]) |
||||||
|
# ---------------------------------- |
||||||
|
# implement the --with-aix-soname flag, and support the `aix-soname=aix' |
||||||
|
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT |
||||||
|
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. |
||||||
|
m4_define([_LT_WITH_AIX_SONAME], |
||||||
|
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl |
||||||
|
shared_archive_member_spec= |
||||||
|
case $host,$enable_shared in |
||||||
|
power*-*-aix[[5-9]]*,yes) |
||||||
|
AC_MSG_CHECKING([which variant of shared library versioning to provide]) |
||||||
|
AC_ARG_WITH([aix-soname], |
||||||
|
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both], |
||||||
|
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], |
||||||
|
[case $withval in |
||||||
|
aix|svr4|both) |
||||||
|
;; |
||||||
|
*) |
||||||
|
AC_MSG_ERROR([Unknown argument to --with-aix-soname]) |
||||||
|
;; |
||||||
|
esac |
||||||
|
lt_cv_with_aix_soname=$with_aix_soname], |
||||||
|
[AC_CACHE_VAL([lt_cv_with_aix_soname], |
||||||
|
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) |
||||||
|
with_aix_soname=$lt_cv_with_aix_soname]) |
||||||
|
AC_MSG_RESULT([$with_aix_soname]) |
||||||
|
if test aix != "$with_aix_soname"; then |
||||||
|
# For the AIX way of multilib, we name the shared archive member |
||||||
|
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', |
||||||
|
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. |
||||||
|
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, |
||||||
|
# the AIX toolchain works better with OBJECT_MODE set (default 32). |
||||||
|
if test 64 = "${OBJECT_MODE-32}"; then |
||||||
|
shared_archive_member_spec=shr_64 |
||||||
|
else |
||||||
|
shared_archive_member_spec=shr |
||||||
|
fi |
||||||
|
fi |
||||||
|
;; |
||||||
|
*) |
||||||
|
with_aix_soname=aix |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
_LT_DECL([], [shared_archive_member_spec], [0], |
||||||
|
[Shared archive member basename, for filename based shared library versioning on AIX])dnl |
||||||
|
])# _LT_WITH_AIX_SONAME |
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) |
||||||
|
|
||||||
|
|
||||||
|
# _LT_WITH_PIC([MODE]) |
||||||
|
# -------------------- |
||||||
|
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' |
||||||
|
# LT_INIT options. |
||||||
|
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. |
||||||
|
m4_define([_LT_WITH_PIC], |
||||||
|
[AC_ARG_WITH([pic], |
||||||
|
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], |
||||||
|
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])], |
||||||
|
[lt_p=${PACKAGE-default} |
||||||
|
case $withval in |
||||||
|
yes|no) pic_mode=$withval ;; |
||||||
|
*) |
||||||
|
pic_mode=default |
||||||
|
# Look at the argument we got. We use all the common list separators. |
||||||
|
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, |
||||||
|
for lt_pkg in $withval; do |
||||||
|
IFS=$lt_save_ifs |
||||||
|
if test "X$lt_pkg" = "X$lt_p"; then |
||||||
|
pic_mode=yes |
||||||
|
fi |
||||||
|
done |
||||||
|
IFS=$lt_save_ifs |
||||||
|
;; |
||||||
|
esac], |
||||||
|
[pic_mode=m4_default([$1], [default])]) |
||||||
|
|
||||||
|
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl |
||||||
|
])# _LT_WITH_PIC |
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) |
||||||
|
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) |
||||||
|
|
||||||
|
# Old name: |
||||||
|
AU_DEFUN([AC_LIBTOOL_PICMODE], |
||||||
|
[_LT_SET_OPTION([LT_INIT], [pic-only]) |
||||||
|
AC_DIAGNOSE([obsolete], |
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you |
||||||
|
put the 'pic-only' option into LT_INIT's first parameter.]) |
||||||
|
]) |
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility: |
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) |
||||||
|
|
||||||
|
## ----------------- ## |
||||||
|
## LTDL_INIT Options ## |
||||||
|
## ----------------- ## |
||||||
|
|
||||||
|
m4_define([_LTDL_MODE], []) |
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], |
||||||
|
[m4_define([_LTDL_MODE], [nonrecursive])]) |
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [recursive], |
||||||
|
[m4_define([_LTDL_MODE], [recursive])]) |
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [subproject], |
||||||
|
[m4_define([_LTDL_MODE], [subproject])]) |
||||||
|
|
||||||
|
m4_define([_LTDL_TYPE], []) |
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [installable], |
||||||
|
[m4_define([_LTDL_TYPE], [installable])]) |
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [convenience], |
||||||
|
[m4_define([_LTDL_TYPE], [convenience])]) |
@ -0,0 +1,124 @@ |
|||||||
|
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- |
||||||
|
# |
||||||
|
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software |
||||||
|
# Foundation, Inc. |
||||||
|
# Written by Gary V. Vaughan, 2004 |
||||||
|
# |
||||||
|
# This file is free software; the Free Software Foundation gives |
||||||
|
# unlimited permission to copy and/or distribute it, with or without |
||||||
|
# modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
# serial 6 ltsugar.m4 |
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define. |
||||||
|
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_join(SEP, ARG1, [ARG2...]) |
||||||
|
# ----------------------------- |
||||||
|
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their |
||||||
|
# associated separator. |
||||||
|
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier |
||||||
|
# versions in m4sugar had bugs. |
||||||
|
m4_define([lt_join], |
||||||
|
[m4_if([$#], [1], [], |
||||||
|
[$#], [2], [[$2]], |
||||||
|
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) |
||||||
|
m4_define([_lt_join], |
||||||
|
[m4_if([$#$2], [2], [], |
||||||
|
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_car(LIST) |
||||||
|
# lt_cdr(LIST) |
||||||
|
# ------------ |
||||||
|
# Manipulate m4 lists. |
||||||
|
# These macros are necessary as long as will still need to support |
||||||
|
# Autoconf-2.59, which quotes differently. |
||||||
|
m4_define([lt_car], [[$1]]) |
||||||
|
m4_define([lt_cdr], |
||||||
|
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], |
||||||
|
[$#], 1, [], |
||||||
|
[m4_dquote(m4_shift($@))])]) |
||||||
|
m4_define([lt_unquote], $1) |
||||||
|
|
||||||
|
|
||||||
|
# lt_append(MACRO-NAME, STRING, [SEPARATOR]) |
||||||
|
# ------------------------------------------ |
||||||
|
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. |
||||||
|
# Note that neither SEPARATOR nor STRING are expanded; they are appended |
||||||
|
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). |
||||||
|
# No SEPARATOR is output if MACRO-NAME was previously undefined (different |
||||||
|
# than defined and empty). |
||||||
|
# |
||||||
|
# This macro is needed until we can rely on Autoconf 2.62, since earlier |
||||||
|
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. |
||||||
|
m4_define([lt_append], |
||||||
|
[m4_define([$1], |
||||||
|
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) |
||||||
|
# ---------------------------------------------------------- |
||||||
|
# Produce a SEP delimited list of all paired combinations of elements of |
||||||
|
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list |
||||||
|
# has the form PREFIXmINFIXSUFFIXn. |
||||||
|
# Needed until we can rely on m4_combine added in Autoconf 2.62. |
||||||
|
m4_define([lt_combine], |
||||||
|
[m4_if(m4_eval([$# > 3]), [1], |
||||||
|
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl |
||||||
|
[[m4_foreach([_Lt_prefix], [$2], |
||||||
|
[m4_foreach([_Lt_suffix], |
||||||
|
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, |
||||||
|
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) |
||||||
|
# ----------------------------------------------------------------------- |
||||||
|
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited |
||||||
|
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. |
||||||
|
m4_define([lt_if_append_uniq], |
||||||
|
[m4_ifdef([$1], |
||||||
|
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], |
||||||
|
[lt_append([$1], [$2], [$3])$4], |
||||||
|
[$5])], |
||||||
|
[lt_append([$1], [$2], [$3])$4])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_add(DICT, KEY, VALUE) |
||||||
|
# ----------------------------- |
||||||
|
m4_define([lt_dict_add], |
||||||
|
[m4_define([$1($2)], [$3])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) |
||||||
|
# -------------------------------------------- |
||||||
|
m4_define([lt_dict_add_subkey], |
||||||
|
[m4_define([$1($2:$3)], [$4])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_fetch(DICT, KEY, [SUBKEY]) |
||||||
|
# ---------------------------------- |
||||||
|
m4_define([lt_dict_fetch], |
||||||
|
[m4_ifval([$3], |
||||||
|
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), |
||||||
|
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) |
||||||
|
# ----------------------------------------------------------------- |
||||||
|
m4_define([lt_if_dict_fetch], |
||||||
|
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], |
||||||
|
[$5], |
||||||
|
[$6])]) |
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) |
||||||
|
# -------------------------------------------------------------- |
||||||
|
m4_define([lt_dict_filter], |
||||||
|
[m4_if([$5], [], [], |
||||||
|
[lt_join(m4_quote(m4_default([$4], [[, ]])), |
||||||
|
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), |
||||||
|
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl |
||||||
|
]) |
@ -0,0 +1,23 @@ |
|||||||
|
# ltversion.m4 -- version numbers -*- Autoconf -*- |
||||||
|
# |
||||||
|
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. |
||||||
|
# Written by Scott James Remnant, 2004 |
||||||
|
# |
||||||
|
# This file is free software; the Free Software Foundation gives |
||||||
|
# unlimited permission to copy and/or distribute it, with or without |
||||||
|
# modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
# @configure_input@ |
||||||
|
|
||||||
|
# serial 4179 ltversion.m4 |
||||||
|
# This file is part of GNU Libtool |
||||||
|
|
||||||
|
m4_define([LT_PACKAGE_VERSION], [2.4.6]) |
||||||
|
m4_define([LT_PACKAGE_REVISION], [2.4.6]) |
||||||
|
|
||||||
|
AC_DEFUN([LTVERSION_VERSION], |
||||||
|
[macro_version='2.4.6' |
||||||
|
macro_revision='2.4.6' |
||||||
|
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) |
||||||
|
_LT_DECL(, macro_revision, 0) |
||||||
|
]) |
@ -0,0 +1,99 @@ |
|||||||
|
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- |
||||||
|
# |
||||||
|
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software |
||||||
|
# Foundation, Inc. |
||||||
|
# Written by Scott James Remnant, 2004. |
||||||
|
# |
||||||
|
# This file is free software; the Free Software Foundation gives |
||||||
|
# unlimited permission to copy and/or distribute it, with or without |
||||||
|
# modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
# serial 5 lt~obsolete.m4 |
||||||
|
|
||||||
|
# These exist entirely to fool aclocal when bootstrapping libtool. |
||||||
|
# |
||||||
|
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), |
||||||
|
# which have later been changed to m4_define as they aren't part of the |
||||||
|
# exported API, or moved to Autoconf or Automake where they belong. |
||||||
|
# |
||||||
|
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN |
||||||
|
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us |
||||||
|
# using a macro with the same name in our local m4/libtool.m4 it'll |
||||||
|
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define |
||||||
|
# and doesn't know about Autoconf macros at all.) |
||||||
|
# |
||||||
|
# So we provide this file, which has a silly filename so it's always |
||||||
|
# included after everything else. This provides aclocal with the |
||||||
|
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything |
||||||
|
# because those macros already exist, or will be overwritten later. |
||||||
|
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. |
||||||
|
# |
||||||
|
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. |
||||||
|
# Yes, that means every name once taken will need to remain here until |
||||||
|
# we give up compatibility with versions before 1.7, at which point |
||||||
|
# we need to keep only those names which we still refer to. |
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define. |
||||||
|
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) |
||||||
|
|
||||||
|
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) |
||||||
|
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) |
||||||
|
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) |
||||||
|
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) |
||||||
|
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) |
||||||
|
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) |
||||||
|
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) |
||||||
|
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) |
||||||
|
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) |
||||||
|
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) |
||||||
|
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) |
||||||
|
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) |
||||||
|
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) |
||||||
|
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) |
||||||
|
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) |
||||||
|
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) |
||||||
|
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) |
||||||
|
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) |
||||||
|
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) |
||||||
|
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) |
||||||
|
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) |
||||||
|
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) |
||||||
|
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) |
||||||
|
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) |
||||||
|
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) |
||||||
|
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) |
||||||
|
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) |
||||||
|
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) |
||||||
|
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) |
||||||
|
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) |
||||||
|
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) |
||||||
|
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) |
||||||
|
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) |
||||||
|
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) |
||||||
|
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) |
||||||
|
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) |
@ -0,0 +1,215 @@ |
|||||||
|
#! /bin/sh |
||||||
|
# Common wrapper for a few potentially missing GNU programs. |
||||||
|
|
||||||
|
scriptversion=2018-03-07.03; # UTC |
||||||
|
|
||||||
|
# Copyright (C) 1996-2020 Free Software Foundation, Inc. |
||||||
|
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. |
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2, or (at your option) |
||||||
|
# any later version. |
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you |
||||||
|
# distribute this file as part of a program that contains a |
||||||
|
# configuration script generated by Autoconf, you may include it under |
||||||
|
# the same distribution terms that you use for the rest of that program. |
||||||
|
|
||||||
|
if test $# -eq 0; then |
||||||
|
echo 1>&2 "Try '$0 --help' for more information" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
case $1 in |
||||||
|
|
||||||
|
--is-lightweight) |
||||||
|
# Used by our autoconf macros to check whether the available missing |
||||||
|
# script is modern enough. |
||||||
|
exit 0 |
||||||
|
;; |
||||||
|
|
||||||
|
--run) |
||||||
|
# Back-compat with the calling convention used by older automake. |
||||||
|
shift |
||||||
|
;; |
||||||
|
|
||||||
|
-h|--h|--he|--hel|--help) |
||||||
|
echo "\ |
||||||
|
$0 [OPTION]... PROGRAM [ARGUMENT]... |
||||||
|
|
||||||
|
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due |
||||||
|
to PROGRAM being missing or too old. |
||||||
|
|
||||||
|
Options: |
||||||
|
-h, --help display this help and exit |
||||||
|
-v, --version output version information and exit |
||||||
|
|
||||||
|
Supported PROGRAM values: |
||||||
|
aclocal autoconf autoheader autom4te automake makeinfo |
||||||
|
bison yacc flex lex help2man |
||||||
|
|
||||||
|
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and |
||||||
|
'g' are ignored when checking the name. |
||||||
|
|
||||||
|
Send bug reports to <bug-automake@gnu.org>." |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
|
||||||
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version) |
||||||
|
echo "missing $scriptversion (GNU Automake)" |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
|
||||||
|
-*) |
||||||
|
echo 1>&2 "$0: unknown '$1' option" |
||||||
|
echo 1>&2 "Try '$0 --help' for more information" |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
|
||||||
|
esac |
||||||
|
|
||||||
|
# Run the given program, remember its exit status. |
||||||
|
"$@"; st=$? |
||||||
|
|
||||||
|
# If it succeeded, we are done. |
||||||
|
test $st -eq 0 && exit 0 |
||||||
|
|
||||||
|
# Also exit now if we it failed (or wasn't found), and '--version' was |
||||||
|
# passed; such an option is passed most likely to detect whether the |
||||||
|
# program is present and works. |
||||||
|
case $2 in --version|--help) exit $st;; esac |
||||||
|
|
||||||
|
# Exit code 63 means version mismatch. This often happens when the user |
||||||
|
# tries to use an ancient version of a tool on a file that requires a |
||||||
|
# minimum version. |
||||||
|
if test $st -eq 63; then |
||||||
|
msg="probably too old" |
||||||
|
elif test $st -eq 127; then |
||||||
|
# Program was missing. |
||||||
|
msg="missing on your system" |
||||||
|
else |
||||||
|
# Program was found and executed, but failed. Give up. |
||||||
|
exit $st |
||||||
|
fi |
||||||
|
|
||||||
|
perl_URL=https://www.perl.org/ |
||||||
|
flex_URL=https://github.com/westes/flex |
||||||
|
gnu_software_URL=https://www.gnu.org/software |
||||||
|
|
||||||
|
program_details () |
||||||
|
{ |
||||||
|
case $1 in |
||||||
|
aclocal|automake) |
||||||
|
echo "The '$1' program is part of the GNU Automake package:" |
||||||
|
echo "<$gnu_software_URL/automake>" |
||||||
|
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" |
||||||
|
echo "<$gnu_software_URL/autoconf>" |
||||||
|
echo "<$gnu_software_URL/m4/>" |
||||||
|
echo "<$perl_URL>" |
||||||
|
;; |
||||||
|
autoconf|autom4te|autoheader) |
||||||
|
echo "The '$1' program is part of the GNU Autoconf package:" |
||||||
|
echo "<$gnu_software_URL/autoconf/>" |
||||||
|
echo "It also requires GNU m4 and Perl in order to run:" |
||||||
|
echo "<$gnu_software_URL/m4/>" |
||||||
|
echo "<$perl_URL>" |
||||||
|
;; |
||||||
|
esac |
||||||
|
} |
||||||
|
|
||||||
|
give_advice () |
||||||
|
{ |
||||||
|
# Normalize program name to check for. |
||||||
|
normalized_program=`echo "$1" | sed ' |
||||||
|
s/^gnu-//; t |
||||||
|
s/^gnu//; t |
||||||
|
s/^g//; t'` |
||||||
|
|
||||||
|
printf '%s\n' "'$1' is $msg." |
||||||
|
|
||||||
|
configure_deps="'configure.ac' or m4 files included by 'configure.ac'" |
||||||
|
case $normalized_program in |
||||||
|
autoconf*) |
||||||
|
echo "You should only need it if you modified 'configure.ac'," |
||||||
|
echo "or m4 files included by it." |
||||||
|
program_details 'autoconf' |
||||||
|
;; |
||||||
|
autoheader*) |
||||||
|
echo "You should only need it if you modified 'acconfig.h' or" |
||||||
|
echo "$configure_deps." |
||||||
|
program_details 'autoheader' |
||||||
|
;; |
||||||
|
automake*) |
||||||
|
echo "You should only need it if you modified 'Makefile.am' or" |
||||||
|
echo "$configure_deps." |
||||||
|
program_details 'automake' |
||||||
|
;; |
||||||
|
aclocal*) |
||||||
|
echo "You should only need it if you modified 'acinclude.m4' or" |
||||||
|
echo "$configure_deps." |
||||||
|
program_details 'aclocal' |
||||||
|
;; |
||||||
|
autom4te*) |
||||||
|
echo "You might have modified some maintainer files that require" |
||||||
|
echo "the 'autom4te' program to be rebuilt." |
||||||
|
program_details 'autom4te' |
||||||
|
;; |
||||||
|
bison*|yacc*) |
||||||
|
echo "You should only need it if you modified a '.y' file." |
||||||
|
echo "You may want to install the GNU Bison package:" |
||||||
|
echo "<$gnu_software_URL/bison/>" |
||||||
|
;; |
||||||
|
lex*|flex*) |
||||||
|
echo "You should only need it if you modified a '.l' file." |
||||||
|
echo "You may want to install the Fast Lexical Analyzer package:" |
||||||
|
echo "<$flex_URL>" |
||||||
|
;; |
||||||
|
help2man*) |
||||||
|
echo "You should only need it if you modified a dependency" \ |
||||||
|
"of a man page." |
||||||
|
echo "You may want to install the GNU Help2man package:" |
||||||
|
echo "<$gnu_software_URL/help2man/>" |
||||||
|
;; |
||||||
|
makeinfo*) |
||||||
|
echo "You should only need it if you modified a '.texi' file, or" |
||||||
|
echo "any other file indirectly affecting the aspect of the manual." |
||||||
|
echo "You might want to install the Texinfo package:" |
||||||
|
echo "<$gnu_software_URL/texinfo/>" |
||||||
|
echo "The spurious makeinfo call might also be the consequence of" |
||||||
|
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" |
||||||
|
echo "want to install GNU make:" |
||||||
|
echo "<$gnu_software_URL/make/>" |
||||||
|
;; |
||||||
|
*) |
||||||
|
echo "You might have modified some files without having the proper" |
||||||
|
echo "tools for further handling them. Check the 'README' file, it" |
||||||
|
echo "often tells you about the needed prerequisites for installing" |
||||||
|
echo "this package. You may also peek at any GNU archive site, in" |
||||||
|
echo "case some other package contains this missing '$1' program." |
||||||
|
;; |
||||||
|
esac |
||||||
|
} |
||||||
|
|
||||||
|
give_advice "$1" | sed -e '1s/^/WARNING: /' \ |
||||||
|
-e '2,$s/^/ /' >&2 |
||||||
|
|
||||||
|
# Propagate the correct exit status (expected to be 127 for a program |
||||||
|
# not found, 63 for a program that failed due to version mismatch). |
||||||
|
exit $st |
||||||
|
|
||||||
|
# Local variables: |
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp) |
||||||
|
# time-stamp-start: "scriptversion=" |
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H" |
||||||
|
# time-stamp-time-zone: "UTC0" |
||||||
|
# time-stamp-end: "; # UTC" |
||||||
|
# End: |
@ -0,0 +1,14 @@ |
|||||||
|
# opusfile uninstalled pkg-config file |
||||||
|
|
||||||
|
prefix= |
||||||
|
exec_prefix= |
||||||
|
libdir=${pcfiledir}/.libs |
||||||
|
includedir=${pcfiledir}/@top_srcdir@/include |
||||||
|
|
||||||
|
Name: opusfile uninstalled |
||||||
|
Description: High-level Opus decoding library (not installed) |
||||||
|
Version: @PACKAGE_VERSION@ |
||||||
|
Requires.private: ogg >= 1.3 opus >= 1.0.1 |
||||||
|
Conflicts: |
||||||
|
Libs: ${libdir}/libopusfile.la @lrintf_lib@ |
||||||
|
Cflags: -I${includedir} |
@ -0,0 +1,15 @@ |
|||||||
|
# opusfile installed pkg-config file |
||||||
|
|
||||||
|
prefix=@prefix@ |
||||||
|
exec_prefix=@exec_prefix@ |
||||||
|
libdir=@libdir@ |
||||||
|
includedir=@includedir@ |
||||||
|
|
||||||
|
Name: opusfile |
||||||
|
Description: High-level Opus decoding library |
||||||
|
Version: @PACKAGE_VERSION@ |
||||||
|
Requires.private: ogg >= 1.3 opus >= 1.0.1 |
||||||
|
Conflicts: |
||||||
|
Libs: -L${libdir} -lopusfile |
||||||
|
Libs.private: @lrintf_lib@ |
||||||
|
Cflags: -I${includedir}/opus |
@ -0,0 +1,14 @@ |
|||||||
|
# opusurl uninstalled pkg-config file |
||||||
|
|
||||||
|
prefix= |
||||||
|
exec_prefix= |
||||||
|
libdir=${pcfiledir}/.libs |
||||||
|
includedir=${pcfiledir}/@top_srcdir@/include |
||||||
|
|
||||||
|
Name: opusfile uninstalled |
||||||
|
Description: High-level Opus decoding library, URL support (not installed) |
||||||
|
Version: @PACKAGE_VERSION@ |
||||||
|
Requires: opusfile |
||||||
|
Requires.private: @openssl@ |
||||||
|
Conflicts: |
||||||
|
Libs: ${libdir}/libopusurl.la |
@ -0,0 +1,14 @@ |
|||||||
|
# opusurl installed pkg-config file |
||||||
|
|
||||||
|
prefix=@prefix@ |
||||||
|
exec_prefix=@exec_prefix@ |
||||||
|
libdir=@libdir@ |
||||||
|
includedir=@includedir@ |
||||||
|
|
||||||
|
Name: opusurl |
||||||
|
Description: High-level Opus decoding library, URL support |
||||||
|
Version: @PACKAGE_VERSION@ |
||||||
|
Requires: opusfile |
||||||
|
Requires.private: @openssl@ |
||||||
|
Conflicts: |
||||||
|
Libs: -L${libdir} -lopusurl |
@ -0,0 +1 @@ |
|||||||
|
PACKAGE_VERSION="0.12" |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,775 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
#ifdef HAVE_CONFIG_H |
||||||
|
#include "config.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "internal.h" |
||||||
|
#include <limits.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
static unsigned op_parse_uint16le(const unsigned char *_data){ |
||||||
|
return _data[0]|_data[1]<<8; |
||||||
|
} |
||||||
|
|
||||||
|
static int op_parse_int16le(const unsigned char *_data){ |
||||||
|
int ret; |
||||||
|
ret=_data[0]|_data[1]<<8; |
||||||
|
return (ret^0x8000)-0x8000; |
||||||
|
} |
||||||
|
|
||||||
|
static opus_uint32 op_parse_uint32le(const unsigned char *_data){ |
||||||
|
return _data[0]|(opus_uint32)_data[1]<<8| |
||||||
|
(opus_uint32)_data[2]<<16|(opus_uint32)_data[3]<<24; |
||||||
|
} |
||||||
|
|
||||||
|
static opus_uint32 op_parse_uint32be(const unsigned char *_data){ |
||||||
|
return _data[3]|(opus_uint32)_data[2]<<8| |
||||||
|
(opus_uint32)_data[1]<<16|(opus_uint32)_data[0]<<24; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_head_parse(OpusHead *_head,const unsigned char *_data,size_t _len){ |
||||||
|
OpusHead head; |
||||||
|
if(_len<8)return OP_ENOTFORMAT; |
||||||
|
if(memcmp(_data,"OpusHead",8)!=0)return OP_ENOTFORMAT; |
||||||
|
if(_len<9)return OP_EBADHEADER; |
||||||
|
head.version=_data[8]; |
||||||
|
if(head.version>15)return OP_EVERSION; |
||||||
|
if(_len<19)return OP_EBADHEADER; |
||||||
|
head.channel_count=_data[9]; |
||||||
|
head.pre_skip=op_parse_uint16le(_data+10); |
||||||
|
head.input_sample_rate=op_parse_uint32le(_data+12); |
||||||
|
head.output_gain=op_parse_int16le(_data+16); |
||||||
|
head.mapping_family=_data[18]; |
||||||
|
if(head.mapping_family==0){ |
||||||
|
if(head.channel_count<1||head.channel_count>2)return OP_EBADHEADER; |
||||||
|
if(head.version<=1&&_len>19)return OP_EBADHEADER; |
||||||
|
head.stream_count=1; |
||||||
|
head.coupled_count=head.channel_count-1; |
||||||
|
if(_head!=NULL){ |
||||||
|
_head->mapping[0]=0; |
||||||
|
_head->mapping[1]=1; |
||||||
|
} |
||||||
|
} |
||||||
|
else if(head.mapping_family==1){ |
||||||
|
size_t size; |
||||||
|
int ci; |
||||||
|
if(head.channel_count<1||head.channel_count>8)return OP_EBADHEADER; |
||||||
|
size=21+head.channel_count; |
||||||
|
if(_len<size||head.version<=1&&_len>size)return OP_EBADHEADER; |
||||||
|
head.stream_count=_data[19]; |
||||||
|
if(head.stream_count<1)return OP_EBADHEADER; |
||||||
|
head.coupled_count=_data[20]; |
||||||
|
if(head.coupled_count>head.stream_count)return OP_EBADHEADER; |
||||||
|
for(ci=0;ci<head.channel_count;ci++){ |
||||||
|
if(_data[21+ci]>=head.stream_count+head.coupled_count |
||||||
|
&&_data[21+ci]!=255){ |
||||||
|
return OP_EBADHEADER; |
||||||
|
} |
||||||
|
} |
||||||
|
if(_head!=NULL)memcpy(_head->mapping,_data+21,head.channel_count); |
||||||
|
} |
||||||
|
/*General purpose players should not attempt to play back content with
|
||||||
|
channel mapping family 255.*/ |
||||||
|
else if(head.mapping_family==255)return OP_EIMPL; |
||||||
|
/*No other channel mapping families are currently defined.*/ |
||||||
|
else return OP_EBADHEADER; |
||||||
|
if(_head!=NULL)memcpy(_head,&head,head.mapping-(unsigned char *)&head); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void opus_tags_init(OpusTags *_tags){ |
||||||
|
memset(_tags,0,sizeof(*_tags)); |
||||||
|
} |
||||||
|
|
||||||
|
void opus_tags_clear(OpusTags *_tags){ |
||||||
|
int ncomments; |
||||||
|
int ci; |
||||||
|
ncomments=_tags->comments; |
||||||
|
if(_tags->user_comments!=NULL)ncomments++; |
||||||
|
else{ |
||||||
|
OP_ASSERT(ncomments==0); |
||||||
|
} |
||||||
|
for(ci=ncomments;ci-->0;)_ogg_free(_tags->user_comments[ci]); |
||||||
|
_ogg_free(_tags->user_comments); |
||||||
|
_ogg_free(_tags->comment_lengths); |
||||||
|
_ogg_free(_tags->vendor); |
||||||
|
} |
||||||
|
|
||||||
|
/*Ensure there's room for up to _ncomments comments.*/ |
||||||
|
static int op_tags_ensure_capacity(OpusTags *_tags,size_t _ncomments){ |
||||||
|
char **user_comments; |
||||||
|
int *comment_lengths; |
||||||
|
int cur_ncomments; |
||||||
|
size_t size; |
||||||
|
if(OP_UNLIKELY(_ncomments>=(size_t)INT_MAX))return OP_EFAULT; |
||||||
|
size=sizeof(*_tags->comment_lengths)*(_ncomments+1); |
||||||
|
if(size/sizeof(*_tags->comment_lengths)!=_ncomments+1)return OP_EFAULT; |
||||||
|
cur_ncomments=_tags->comments; |
||||||
|
/*We only support growing.
|
||||||
|
Trimming requires cleaning up the allocated strings in the old space, and |
||||||
|
is best handled separately if it's ever needed.*/ |
||||||
|
OP_ASSERT(_ncomments>=(size_t)cur_ncomments); |
||||||
|
comment_lengths=(int *)_ogg_realloc(_tags->comment_lengths,size); |
||||||
|
if(OP_UNLIKELY(comment_lengths==NULL))return OP_EFAULT; |
||||||
|
if(_tags->comment_lengths==NULL){ |
||||||
|
OP_ASSERT(cur_ncomments==0); |
||||||
|
comment_lengths[cur_ncomments]=0; |
||||||
|
} |
||||||
|
comment_lengths[_ncomments]=comment_lengths[cur_ncomments]; |
||||||
|
_tags->comment_lengths=comment_lengths; |
||||||
|
size=sizeof(*_tags->user_comments)*(_ncomments+1); |
||||||
|
if(size/sizeof(*_tags->user_comments)!=_ncomments+1)return OP_EFAULT; |
||||||
|
user_comments=(char **)_ogg_realloc(_tags->user_comments,size); |
||||||
|
if(OP_UNLIKELY(user_comments==NULL))return OP_EFAULT; |
||||||
|
if(_tags->user_comments==NULL){ |
||||||
|
OP_ASSERT(cur_ncomments==0); |
||||||
|
user_comments[cur_ncomments]=NULL; |
||||||
|
} |
||||||
|
user_comments[_ncomments]=user_comments[cur_ncomments]; |
||||||
|
_tags->user_comments=user_comments; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*Duplicate a (possibly non-NUL terminated) string with a known length.*/ |
||||||
|
static char *op_strdup_with_len(const char *_s,size_t _len){ |
||||||
|
size_t size; |
||||||
|
char *ret; |
||||||
|
size=sizeof(*ret)*(_len+1); |
||||||
|
if(OP_UNLIKELY(size<_len))return NULL; |
||||||
|
ret=(char *)_ogg_malloc(size); |
||||||
|
if(OP_LIKELY(ret!=NULL)){ |
||||||
|
ret=(char *)memcpy(ret,_s,sizeof(*ret)*_len); |
||||||
|
ret[_len]='\0'; |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
/*The actual implementation of opus_tags_parse().
|
||||||
|
Unlike the public API, this function requires _tags to already be |
||||||
|
initialized, modifies its contents before success is guaranteed, and assumes |
||||||
|
the caller will clear it on error.*/ |
||||||
|
static int opus_tags_parse_impl(OpusTags *_tags, |
||||||
|
const unsigned char *_data,size_t _len){ |
||||||
|
opus_uint32 count; |
||||||
|
size_t len; |
||||||
|
int ncomments; |
||||||
|
int ci; |
||||||
|
len=_len; |
||||||
|
if(len<8)return OP_ENOTFORMAT; |
||||||
|
if(memcmp(_data,"OpusTags",8)!=0)return OP_ENOTFORMAT; |
||||||
|
if(len<16)return OP_EBADHEADER; |
||||||
|
_data+=8; |
||||||
|
len-=8; |
||||||
|
count=op_parse_uint32le(_data); |
||||||
|
_data+=4; |
||||||
|
len-=4; |
||||||
|
if(count>len)return OP_EBADHEADER; |
||||||
|
if(_tags!=NULL){ |
||||||
|
_tags->vendor=op_strdup_with_len((char *)_data,count); |
||||||
|
if(_tags->vendor==NULL)return OP_EFAULT; |
||||||
|
} |
||||||
|
_data+=count; |
||||||
|
len-=count; |
||||||
|
if(len<4)return OP_EBADHEADER; |
||||||
|
count=op_parse_uint32le(_data); |
||||||
|
_data+=4; |
||||||
|
len-=4; |
||||||
|
/*Check to make sure there's minimally sufficient data left in the packet.*/ |
||||||
|
if(count>len>>2)return OP_EBADHEADER; |
||||||
|
/*Check for overflow (the API limits this to an int).*/ |
||||||
|
if(count>(opus_uint32)INT_MAX-1)return OP_EFAULT; |
||||||
|
if(_tags!=NULL){ |
||||||
|
int ret; |
||||||
|
ret=op_tags_ensure_capacity(_tags,count); |
||||||
|
if(ret<0)return ret; |
||||||
|
} |
||||||
|
ncomments=(int)count; |
||||||
|
for(ci=0;ci<ncomments;ci++){ |
||||||
|
/*Check to make sure there's minimally sufficient data left in the packet.*/ |
||||||
|
if((size_t)(ncomments-ci)>len>>2)return OP_EBADHEADER; |
||||||
|
count=op_parse_uint32le(_data); |
||||||
|
_data+=4; |
||||||
|
len-=4; |
||||||
|
if(count>len)return OP_EBADHEADER; |
||||||
|
/*Check for overflow (the API limits this to an int).*/ |
||||||
|
if(count>(opus_uint32)INT_MAX)return OP_EFAULT; |
||||||
|
if(_tags!=NULL){ |
||||||
|
_tags->user_comments[ci]=op_strdup_with_len((char *)_data,count); |
||||||
|
if(_tags->user_comments[ci]==NULL)return OP_EFAULT; |
||||||
|
_tags->comment_lengths[ci]=(int)count; |
||||||
|
_tags->comments=ci+1; |
||||||
|
/*Needed by opus_tags_clear() if we fail before parsing the (optional)
|
||||||
|
binary metadata.*/ |
||||||
|
_tags->user_comments[ci+1]=NULL; |
||||||
|
} |
||||||
|
_data+=count; |
||||||
|
len-=count; |
||||||
|
} |
||||||
|
if(len>0&&(_data[0]&1)){ |
||||||
|
if(len>(opus_uint32)INT_MAX)return OP_EFAULT; |
||||||
|
if(_tags!=NULL){ |
||||||
|
_tags->user_comments[ncomments]=(char *)_ogg_malloc(len); |
||||||
|
if(OP_UNLIKELY(_tags->user_comments[ncomments]==NULL))return OP_EFAULT; |
||||||
|
memcpy(_tags->user_comments[ncomments],_data,len); |
||||||
|
_tags->comment_lengths[ncomments]=(int)len; |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_parse(OpusTags *_tags,const unsigned char *_data,size_t _len){ |
||||||
|
if(_tags!=NULL){ |
||||||
|
OpusTags tags; |
||||||
|
int ret; |
||||||
|
opus_tags_init(&tags); |
||||||
|
ret=opus_tags_parse_impl(&tags,_data,_len); |
||||||
|
if(ret<0)opus_tags_clear(&tags); |
||||||
|
else *_tags=*&tags; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
else return opus_tags_parse_impl(NULL,_data,_len); |
||||||
|
} |
||||||
|
|
||||||
|
/*The actual implementation of opus_tags_copy().
|
||||||
|
Unlike the public API, this function requires _dst to already be |
||||||
|
initialized, modifies its contents before success is guaranteed, and assumes |
||||||
|
the caller will clear it on error.*/ |
||||||
|
static int opus_tags_copy_impl(OpusTags *_dst,const OpusTags *_src){ |
||||||
|
char *vendor; |
||||||
|
int ncomments; |
||||||
|
int ret; |
||||||
|
int ci; |
||||||
|
vendor=_src->vendor; |
||||||
|
_dst->vendor=op_strdup_with_len(vendor,strlen(vendor)); |
||||||
|
if(OP_UNLIKELY(_dst->vendor==NULL))return OP_EFAULT; |
||||||
|
ncomments=_src->comments; |
||||||
|
ret=op_tags_ensure_capacity(_dst,ncomments); |
||||||
|
if(OP_UNLIKELY(ret<0))return ret; |
||||||
|
for(ci=0;ci<ncomments;ci++){ |
||||||
|
int len; |
||||||
|
len=_src->comment_lengths[ci]; |
||||||
|
OP_ASSERT(len>=0); |
||||||
|
_dst->user_comments[ci]=op_strdup_with_len(_src->user_comments[ci],len); |
||||||
|
if(OP_UNLIKELY(_dst->user_comments[ci]==NULL))return OP_EFAULT; |
||||||
|
_dst->comment_lengths[ci]=len; |
||||||
|
_dst->comments=ci+1; |
||||||
|
} |
||||||
|
if(_src->comment_lengths!=NULL){ |
||||||
|
int len; |
||||||
|
len=_src->comment_lengths[ncomments]; |
||||||
|
if(len>0){ |
||||||
|
_dst->user_comments[ncomments]=(char *)_ogg_malloc(len); |
||||||
|
if(OP_UNLIKELY(_dst->user_comments[ncomments]==NULL))return OP_EFAULT; |
||||||
|
memcpy(_dst->user_comments[ncomments],_src->user_comments[ncomments],len); |
||||||
|
_dst->comment_lengths[ncomments]=len; |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_copy(OpusTags *_dst,const OpusTags *_src){ |
||||||
|
OpusTags dst; |
||||||
|
int ret; |
||||||
|
opus_tags_init(&dst); |
||||||
|
ret=opus_tags_copy_impl(&dst,_src); |
||||||
|
if(OP_UNLIKELY(ret<0))opus_tags_clear(&dst); |
||||||
|
else *_dst=*&dst; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value){ |
||||||
|
char *comment; |
||||||
|
size_t tag_len; |
||||||
|
size_t value_len; |
||||||
|
int ncomments; |
||||||
|
int ret; |
||||||
|
ncomments=_tags->comments; |
||||||
|
ret=op_tags_ensure_capacity(_tags,ncomments+1); |
||||||
|
if(OP_UNLIKELY(ret<0))return ret; |
||||||
|
tag_len=strlen(_tag); |
||||||
|
value_len=strlen(_value); |
||||||
|
/*+2 for '=' and '\0'.*/ |
||||||
|
if(tag_len+value_len<tag_len)return OP_EFAULT; |
||||||
|
if(tag_len+value_len>(size_t)INT_MAX-2)return OP_EFAULT; |
||||||
|
comment=(char *)_ogg_malloc(sizeof(*comment)*(tag_len+value_len+2)); |
||||||
|
if(OP_UNLIKELY(comment==NULL))return OP_EFAULT; |
||||||
|
memcpy(comment,_tag,sizeof(*comment)*tag_len); |
||||||
|
comment[tag_len]='='; |
||||||
|
memcpy(comment+tag_len+1,_value,sizeof(*comment)*(value_len+1)); |
||||||
|
_tags->user_comments[ncomments]=comment; |
||||||
|
_tags->comment_lengths[ncomments]=(int)(tag_len+value_len+1); |
||||||
|
_tags->comments=ncomments+1; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_add_comment(OpusTags *_tags,const char *_comment){ |
||||||
|
char *comment; |
||||||
|
int comment_len; |
||||||
|
int ncomments; |
||||||
|
int ret; |
||||||
|
ncomments=_tags->comments; |
||||||
|
ret=op_tags_ensure_capacity(_tags,ncomments+1); |
||||||
|
if(OP_UNLIKELY(ret<0))return ret; |
||||||
|
comment_len=(int)strlen(_comment); |
||||||
|
comment=op_strdup_with_len(_comment,comment_len); |
||||||
|
if(OP_UNLIKELY(comment==NULL))return OP_EFAULT; |
||||||
|
_tags->user_comments[ncomments]=comment; |
||||||
|
_tags->comment_lengths[ncomments]=comment_len; |
||||||
|
_tags->comments=ncomments+1; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_set_binary_suffix(OpusTags *_tags, |
||||||
|
const unsigned char *_data,int _len){ |
||||||
|
unsigned char *binary_suffix_data; |
||||||
|
int ncomments; |
||||||
|
int ret; |
||||||
|
if(_len<0||_len>0&&(_data==NULL||!(_data[0]&1)))return OP_EINVAL; |
||||||
|
ncomments=_tags->comments; |
||||||
|
ret=op_tags_ensure_capacity(_tags,ncomments); |
||||||
|
if(OP_UNLIKELY(ret<0))return ret; |
||||||
|
binary_suffix_data= |
||||||
|
(unsigned char *)_ogg_realloc(_tags->user_comments[ncomments],_len); |
||||||
|
if(OP_UNLIKELY(binary_suffix_data==NULL))return OP_EFAULT; |
||||||
|
memcpy(binary_suffix_data,_data,_len); |
||||||
|
_tags->user_comments[ncomments]=(char *)binary_suffix_data; |
||||||
|
_tags->comment_lengths[ncomments]=_len; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tagcompare(const char *_tag_name,const char *_comment){ |
||||||
|
size_t tag_len; |
||||||
|
tag_len=strlen(_tag_name); |
||||||
|
if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return -1; |
||||||
|
return opus_tagncompare(_tag_name,(int)tag_len,_comment); |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment){ |
||||||
|
int ret; |
||||||
|
OP_ASSERT(_tag_len>=0); |
||||||
|
ret=op_strncasecmp(_tag_name,_comment,_tag_len); |
||||||
|
return ret?ret:'='-_comment[_tag_len]; |
||||||
|
} |
||||||
|
|
||||||
|
const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){ |
||||||
|
char **user_comments; |
||||||
|
size_t tag_len; |
||||||
|
int found; |
||||||
|
int ncomments; |
||||||
|
int ci; |
||||||
|
tag_len=strlen(_tag); |
||||||
|
if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return NULL; |
||||||
|
ncomments=_tags->comments; |
||||||
|
user_comments=_tags->user_comments; |
||||||
|
found=0; |
||||||
|
for(ci=0;ci<ncomments;ci++){ |
||||||
|
if(!opus_tagncompare(_tag,(int)tag_len,user_comments[ci])){ |
||||||
|
/*We return a pointer to the data, not a copy.*/ |
||||||
|
if(_count==found++)return user_comments[ci]+tag_len+1; |
||||||
|
} |
||||||
|
} |
||||||
|
/*Didn't find anything.*/ |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_query_count(const OpusTags *_tags,const char *_tag){ |
||||||
|
char **user_comments; |
||||||
|
size_t tag_len; |
||||||
|
int found; |
||||||
|
int ncomments; |
||||||
|
int ci; |
||||||
|
tag_len=strlen(_tag); |
||||||
|
if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return 0; |
||||||
|
ncomments=_tags->comments; |
||||||
|
user_comments=_tags->user_comments; |
||||||
|
found=0; |
||||||
|
for(ci=0;ci<ncomments;ci++){ |
||||||
|
if(!opus_tagncompare(_tag,(int)tag_len,user_comments[ci]))found++; |
||||||
|
} |
||||||
|
return found; |
||||||
|
} |
||||||
|
|
||||||
|
const unsigned char *opus_tags_get_binary_suffix(const OpusTags *_tags, |
||||||
|
int *_len){ |
||||||
|
int ncomments; |
||||||
|
int len; |
||||||
|
ncomments=_tags->comments; |
||||||
|
len=_tags->comment_lengths==NULL?0:_tags->comment_lengths[ncomments]; |
||||||
|
*_len=len; |
||||||
|
OP_ASSERT(len==0||_tags->user_comments!=NULL); |
||||||
|
return len>0?(const unsigned char *)_tags->user_comments[ncomments]:NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static int opus_tags_get_gain(const OpusTags *_tags,int *_gain_q8, |
||||||
|
const char *_tag_name,size_t _tag_len){ |
||||||
|
char **comments; |
||||||
|
int ncomments; |
||||||
|
int ci; |
||||||
|
comments=_tags->user_comments; |
||||||
|
ncomments=_tags->comments; |
||||||
|
/*Look for the first valid tag with the name _tag_name and use that.*/ |
||||||
|
for(ci=0;ci<ncomments;ci++){ |
||||||
|
OP_ASSERT(_tag_len<=(size_t)INT_MAX); |
||||||
|
if(opus_tagncompare(_tag_name,(int)_tag_len,comments[ci])==0){ |
||||||
|
char *p; |
||||||
|
opus_int32 gain_q8; |
||||||
|
int negative; |
||||||
|
p=comments[ci]+_tag_len+1; |
||||||
|
negative=0; |
||||||
|
if(*p=='-'){ |
||||||
|
negative=-1; |
||||||
|
p++; |
||||||
|
} |
||||||
|
else if(*p=='+')p++; |
||||||
|
gain_q8=0; |
||||||
|
while(*p>='0'&&*p<='9'){ |
||||||
|
gain_q8=10*gain_q8+*p-'0'; |
||||||
|
if(gain_q8>32767-negative)break; |
||||||
|
p++; |
||||||
|
} |
||||||
|
/*This didn't look like a signed 16-bit decimal integer.
|
||||||
|
Not a valid gain tag.*/ |
||||||
|
if(*p!='\0')continue; |
||||||
|
*_gain_q8=(int)(gain_q8+negative^negative); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
return OP_FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_get_album_gain(const OpusTags *_tags,int *_gain_q8){ |
||||||
|
return opus_tags_get_gain(_tags,_gain_q8,"R128_ALBUM_GAIN",15); |
||||||
|
} |
||||||
|
|
||||||
|
int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8){ |
||||||
|
return opus_tags_get_gain(_tags,_gain_q8,"R128_TRACK_GAIN",15); |
||||||
|
} |
||||||
|
|
||||||
|
static int op_is_jpeg(const unsigned char *_buf,size_t _buf_sz){ |
||||||
|
return _buf_sz>=3&&memcmp(_buf,"\xFF\xD8\xFF",3)==0; |
||||||
|
} |
||||||
|
|
||||||
|
/*Tries to extract the width, height, bits per pixel, and palette size of a
|
||||||
|
JPEG. |
||||||
|
On failure, simply leaves its outputs unmodified.*/ |
||||||
|
static void op_extract_jpeg_params(const unsigned char *_buf,size_t _buf_sz, |
||||||
|
opus_uint32 *_width,opus_uint32 *_height, |
||||||
|
opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){ |
||||||
|
if(op_is_jpeg(_buf,_buf_sz)){ |
||||||
|
size_t offs; |
||||||
|
offs=2; |
||||||
|
for(;;){ |
||||||
|
size_t segment_len; |
||||||
|
int marker; |
||||||
|
while(offs<_buf_sz&&_buf[offs]!=0xFF)offs++; |
||||||
|
while(offs<_buf_sz&&_buf[offs]==0xFF)offs++; |
||||||
|
marker=_buf[offs]; |
||||||
|
offs++; |
||||||
|
/*If we hit EOI* (end of image), or another SOI* (start of image),
|
||||||
|
or SOS (start of scan), then stop now.*/ |
||||||
|
if(offs>=_buf_sz||(marker>=0xD8&&marker<=0xDA))break; |
||||||
|
/*RST* (restart markers): skip (no segment length).*/ |
||||||
|
else if(marker>=0xD0&&marker<=0xD7)continue; |
||||||
|
/*Read the length of the marker segment.*/ |
||||||
|
if(_buf_sz-offs<2)break; |
||||||
|
segment_len=_buf[offs]<<8|_buf[offs+1]; |
||||||
|
if(segment_len<2||_buf_sz-offs<segment_len)break; |
||||||
|
if(marker==0xC0||(marker>0xC0&&marker<0xD0&&(marker&3)!=0)){ |
||||||
|
/*Found a SOFn (start of frame) marker segment:*/ |
||||||
|
if(segment_len>=8){ |
||||||
|
*_height=_buf[offs+3]<<8|_buf[offs+4]; |
||||||
|
*_width=_buf[offs+5]<<8|_buf[offs+6]; |
||||||
|
*_depth=_buf[offs+2]*_buf[offs+7]; |
||||||
|
*_colors=0; |
||||||
|
*_has_palette=0; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
/*Other markers: skip the whole marker segment.*/ |
||||||
|
offs+=segment_len; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static int op_is_png(const unsigned char *_buf,size_t _buf_sz){ |
||||||
|
return _buf_sz>=8&&memcmp(_buf,"\x89PNG\x0D\x0A\x1A\x0A",8)==0; |
||||||
|
} |
||||||
|
|
||||||
|
/*Tries to extract the width, height, bits per pixel, and palette size of a
|
||||||
|
PNG. |
||||||
|
On failure, simply leaves its outputs unmodified.*/ |
||||||
|
static void op_extract_png_params(const unsigned char *_buf,size_t _buf_sz, |
||||||
|
opus_uint32 *_width,opus_uint32 *_height, |
||||||
|
opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){ |
||||||
|
if(op_is_png(_buf,_buf_sz)){ |
||||||
|
size_t offs; |
||||||
|
offs=8; |
||||||
|
while(_buf_sz-offs>=12){ |
||||||
|
ogg_uint32_t chunk_len; |
||||||
|
chunk_len=op_parse_uint32be(_buf+offs); |
||||||
|
if(chunk_len>_buf_sz-(offs+12))break; |
||||||
|
else if(chunk_len==13&&memcmp(_buf+offs+4,"IHDR",4)==0){ |
||||||
|
int color_type; |
||||||
|
*_width=op_parse_uint32be(_buf+offs+8); |
||||||
|
*_height=op_parse_uint32be(_buf+offs+12); |
||||||
|
color_type=_buf[offs+17]; |
||||||
|
if(color_type==3){ |
||||||
|
*_depth=24; |
||||||
|
*_has_palette=1; |
||||||
|
} |
||||||
|
else{ |
||||||
|
int sample_depth; |
||||||
|
sample_depth=_buf[offs+16]; |
||||||
|
if(color_type==0)*_depth=sample_depth; |
||||||
|
else if(color_type==2)*_depth=sample_depth*3; |
||||||
|
else if(color_type==4)*_depth=sample_depth*2; |
||||||
|
else if(color_type==6)*_depth=sample_depth*4; |
||||||
|
*_colors=0; |
||||||
|
*_has_palette=0; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
else if(*_has_palette>0&&memcmp(_buf+offs+4,"PLTE",4)==0){ |
||||||
|
*_colors=chunk_len/3; |
||||||
|
break; |
||||||
|
} |
||||||
|
offs+=12+chunk_len; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static int op_is_gif(const unsigned char *_buf,size_t _buf_sz){ |
||||||
|
return _buf_sz>=6&&(memcmp(_buf,"GIF87a",6)==0||memcmp(_buf,"GIF89a",6)==0); |
||||||
|
} |
||||||
|
|
||||||
|
/*Tries to extract the width, height, bits per pixel, and palette size of a
|
||||||
|
GIF. |
||||||
|
On failure, simply leaves its outputs unmodified.*/ |
||||||
|
static void op_extract_gif_params(const unsigned char *_buf,size_t _buf_sz, |
||||||
|
opus_uint32 *_width,opus_uint32 *_height, |
||||||
|
opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){ |
||||||
|
if(op_is_gif(_buf,_buf_sz)&&_buf_sz>=14){ |
||||||
|
*_width=_buf[6]|_buf[7]<<8; |
||||||
|
*_height=_buf[8]|_buf[9]<<8; |
||||||
|
/*libFLAC hard-codes the depth to 24.*/ |
||||||
|
*_depth=24; |
||||||
|
*_colors=1<<((_buf[10]&7)+1); |
||||||
|
*_has_palette=1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*The actual implementation of opus_picture_tag_parse().
|
||||||
|
Unlike the public API, this function requires _pic to already be |
||||||
|
initialized, modifies its contents before success is guaranteed, and assumes |
||||||
|
the caller will clear it on error.*/ |
||||||
|
static int opus_picture_tag_parse_impl(OpusPictureTag *_pic,const char *_tag, |
||||||
|
unsigned char *_buf,size_t _buf_sz,size_t _base64_sz){ |
||||||
|
opus_int32 picture_type; |
||||||
|
opus_uint32 mime_type_length; |
||||||
|
char *mime_type; |
||||||
|
opus_uint32 description_length; |
||||||
|
char *description; |
||||||
|
opus_uint32 width; |
||||||
|
opus_uint32 height; |
||||||
|
opus_uint32 depth; |
||||||
|
opus_uint32 colors; |
||||||
|
opus_uint32 data_length; |
||||||
|
opus_uint32 file_width; |
||||||
|
opus_uint32 file_height; |
||||||
|
opus_uint32 file_depth; |
||||||
|
opus_uint32 file_colors; |
||||||
|
int format; |
||||||
|
int has_palette; |
||||||
|
int colors_set; |
||||||
|
size_t i; |
||||||
|
/*Decode the BASE64 data.*/ |
||||||
|
OP_ASSERT(_base64_sz>=11); |
||||||
|
for(i=0;i<_base64_sz;i++){ |
||||||
|
opus_uint32 value; |
||||||
|
int j; |
||||||
|
value=0; |
||||||
|
for(j=0;j<4;j++){ |
||||||
|
unsigned c; |
||||||
|
unsigned d; |
||||||
|
c=(unsigned char)_tag[4*i+j]; |
||||||
|
if(c=='+')d=62; |
||||||
|
else if(c=='/')d=63; |
||||||
|
else if(c>='0'&&c<='9')d=52+c-'0'; |
||||||
|
else if(c>='a'&&c<='z')d=26+c-'a'; |
||||||
|
else if(c>='A'&&c<='Z')d=c-'A'; |
||||||
|
else if(c=='='&&3*i+j>_buf_sz)d=0; |
||||||
|
else return OP_ENOTFORMAT; |
||||||
|
value=value<<6|d; |
||||||
|
} |
||||||
|
_buf[3*i]=(unsigned char)(value>>16); |
||||||
|
if(3*i+1<_buf_sz){ |
||||||
|
_buf[3*i+1]=(unsigned char)(value>>8); |
||||||
|
if(3*i+2<_buf_sz)_buf[3*i+2]=(unsigned char)value; |
||||||
|
} |
||||||
|
} |
||||||
|
i=0; |
||||||
|
picture_type=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
/*Extract the MIME type.*/ |
||||||
|
mime_type_length=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
if(mime_type_length>_buf_sz-32)return OP_ENOTFORMAT; |
||||||
|
mime_type=(char *)_ogg_malloc(sizeof(*_pic->mime_type)*(mime_type_length+1)); |
||||||
|
if(mime_type==NULL)return OP_EFAULT; |
||||||
|
memcpy(mime_type,_buf+i,sizeof(*mime_type)*mime_type_length); |
||||||
|
mime_type[mime_type_length]='\0'; |
||||||
|
_pic->mime_type=mime_type; |
||||||
|
i+=mime_type_length; |
||||||
|
/*Extract the description string.*/ |
||||||
|
description_length=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
if(description_length>_buf_sz-mime_type_length-32)return OP_ENOTFORMAT; |
||||||
|
description= |
||||||
|
(char *)_ogg_malloc(sizeof(*_pic->mime_type)*(description_length+1)); |
||||||
|
if(description==NULL)return OP_EFAULT; |
||||||
|
memcpy(description,_buf+i,sizeof(*description)*description_length); |
||||||
|
description[description_length]='\0'; |
||||||
|
_pic->description=description; |
||||||
|
i+=description_length; |
||||||
|
/*Extract the remaining fields.*/ |
||||||
|
width=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
height=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
depth=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
colors=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
/*If one of these is set, they all must be, but colors==0 is a valid value.*/ |
||||||
|
colors_set=width!=0||height!=0||depth!=0||colors!=0; |
||||||
|
if((width==0||height==0||depth==0)&&colors_set)return OP_ENOTFORMAT; |
||||||
|
data_length=op_parse_uint32be(_buf+i); |
||||||
|
i+=4; |
||||||
|
if(data_length>_buf_sz-i)return OP_ENOTFORMAT; |
||||||
|
/*Trim extraneous data so we don't copy it below.*/ |
||||||
|
_buf_sz=i+data_length; |
||||||
|
/*Attempt to determine the image format.*/ |
||||||
|
format=OP_PIC_FORMAT_UNKNOWN; |
||||||
|
if(mime_type_length==3&&strcmp(mime_type,"-->")==0){ |
||||||
|
format=OP_PIC_FORMAT_URL; |
||||||
|
/*Picture type 1 must be a 32x32 PNG.*/ |
||||||
|
if(picture_type==1&&(width!=0||height!=0)&&(width!=32||height!=32)){ |
||||||
|
return OP_ENOTFORMAT; |
||||||
|
} |
||||||
|
/*Append a terminating NUL for the convenience of our callers.*/ |
||||||
|
_buf[_buf_sz++]='\0'; |
||||||
|
} |
||||||
|
else{ |
||||||
|
if(mime_type_length==10 |
||||||
|
&&op_strncasecmp(mime_type,"image/jpeg",mime_type_length)==0){ |
||||||
|
if(op_is_jpeg(_buf+i,data_length))format=OP_PIC_FORMAT_JPEG; |
||||||
|
} |
||||||
|
else if(mime_type_length==9 |
||||||
|
&&op_strncasecmp(mime_type,"image/png",mime_type_length)==0){ |
||||||
|
if(op_is_png(_buf+i,data_length))format=OP_PIC_FORMAT_PNG; |
||||||
|
} |
||||||
|
else if(mime_type_length==9 |
||||||
|
&&op_strncasecmp(mime_type,"image/gif",mime_type_length)==0){ |
||||||
|
if(op_is_gif(_buf+i,data_length))format=OP_PIC_FORMAT_GIF; |
||||||
|
} |
||||||
|
else if(mime_type_length==0||(mime_type_length==6 |
||||||
|
&&op_strncasecmp(mime_type,"image/",mime_type_length)==0)){ |
||||||
|
if(op_is_jpeg(_buf+i,data_length))format=OP_PIC_FORMAT_JPEG; |
||||||
|
else if(op_is_png(_buf+i,data_length))format=OP_PIC_FORMAT_PNG; |
||||||
|
else if(op_is_gif(_buf+i,data_length))format=OP_PIC_FORMAT_GIF; |
||||||
|
} |
||||||
|
file_width=file_height=file_depth=file_colors=0; |
||||||
|
has_palette=-1; |
||||||
|
switch(format){ |
||||||
|
case OP_PIC_FORMAT_JPEG:{ |
||||||
|
op_extract_jpeg_params(_buf+i,data_length, |
||||||
|
&file_width,&file_height,&file_depth,&file_colors,&has_palette); |
||||||
|
}break; |
||||||
|
case OP_PIC_FORMAT_PNG:{ |
||||||
|
op_extract_png_params(_buf+i,data_length, |
||||||
|
&file_width,&file_height,&file_depth,&file_colors,&has_palette); |
||||||
|
}break; |
||||||
|
case OP_PIC_FORMAT_GIF:{ |
||||||
|
op_extract_gif_params(_buf+i,data_length, |
||||||
|
&file_width,&file_height,&file_depth,&file_colors,&has_palette); |
||||||
|
}break; |
||||||
|
} |
||||||
|
if(has_palette>=0){ |
||||||
|
/*If we successfully extracted these parameters from the image, override
|
||||||
|
any declared values.*/ |
||||||
|
width=file_width; |
||||||
|
height=file_height; |
||||||
|
depth=file_depth; |
||||||
|
colors=file_colors; |
||||||
|
} |
||||||
|
/*Picture type 1 must be a 32x32 PNG.*/ |
||||||
|
if(picture_type==1&&(format!=OP_PIC_FORMAT_PNG||width!=32||height!=32)){ |
||||||
|
return OP_ENOTFORMAT; |
||||||
|
} |
||||||
|
} |
||||||
|
/*Adjust _buf_sz instead of using data_length to capture the terminating NUL
|
||||||
|
for URLs.*/ |
||||||
|
_buf_sz-=i; |
||||||
|
memmove(_buf,_buf+i,sizeof(*_buf)*_buf_sz); |
||||||
|
_buf=(unsigned char *)_ogg_realloc(_buf,_buf_sz); |
||||||
|
if(_buf_sz>0&&_buf==NULL)return OP_EFAULT; |
||||||
|
_pic->type=picture_type; |
||||||
|
_pic->width=width; |
||||||
|
_pic->height=height; |
||||||
|
_pic->depth=depth; |
||||||
|
_pic->colors=colors; |
||||||
|
_pic->data_length=data_length; |
||||||
|
_pic->data=_buf; |
||||||
|
_pic->format=format; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int opus_picture_tag_parse(OpusPictureTag *_pic,const char *_tag){ |
||||||
|
OpusPictureTag pic; |
||||||
|
unsigned char *buf; |
||||||
|
size_t base64_sz; |
||||||
|
size_t buf_sz; |
||||||
|
size_t tag_length; |
||||||
|
int ret; |
||||||
|
if(opus_tagncompare("METADATA_BLOCK_PICTURE",22,_tag)==0)_tag+=23; |
||||||
|
/*Figure out how much BASE64-encoded data we have.*/ |
||||||
|
tag_length=strlen(_tag); |
||||||
|
if(tag_length&3)return OP_ENOTFORMAT; |
||||||
|
base64_sz=tag_length>>2; |
||||||
|
buf_sz=3*base64_sz; |
||||||
|
if(buf_sz<32)return OP_ENOTFORMAT; |
||||||
|
if(_tag[tag_length-1]=='=')buf_sz--; |
||||||
|
if(_tag[tag_length-2]=='=')buf_sz--; |
||||||
|
if(buf_sz<32)return OP_ENOTFORMAT; |
||||||
|
/*Allocate an extra byte to allow appending a terminating NUL to URL data.*/ |
||||||
|
buf=(unsigned char *)_ogg_malloc(sizeof(*buf)*(buf_sz+1)); |
||||||
|
if(buf==NULL)return OP_EFAULT; |
||||||
|
opus_picture_tag_init(&pic); |
||||||
|
ret=opus_picture_tag_parse_impl(&pic,_tag,buf,buf_sz,base64_sz); |
||||||
|
if(ret<0){ |
||||||
|
opus_picture_tag_clear(&pic); |
||||||
|
_ogg_free(buf); |
||||||
|
} |
||||||
|
else *_pic=*&pic; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void opus_picture_tag_init(OpusPictureTag *_pic){ |
||||||
|
memset(_pic,0,sizeof(*_pic)); |
||||||
|
} |
||||||
|
|
||||||
|
void opus_picture_tag_clear(OpusPictureTag *_pic){ |
||||||
|
_ogg_free(_pic->description); |
||||||
|
_ogg_free(_pic->mime_type); |
||||||
|
_ogg_free(_pic->data); |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
#ifdef HAVE_CONFIG_H |
||||||
|
#include "config.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "internal.h" |
||||||
|
|
||||||
|
#if defined(OP_ENABLE_ASSERTIONS) |
||||||
|
void op_fatal_impl(const char *_str,const char *_file,int _line){ |
||||||
|
fprintf(stderr,"Fatal (internal) error in %s, line %i: %s\n", |
||||||
|
_file,_line,_str); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/*A version of strncasecmp() that is guaranteed to only ignore the case of
|
||||||
|
ASCII characters.*/ |
||||||
|
int op_strncasecmp(const char *_a,const char *_b,int _n){ |
||||||
|
int i; |
||||||
|
for(i=0;i<_n;i++){ |
||||||
|
int a; |
||||||
|
int b; |
||||||
|
int d; |
||||||
|
a=_a[i]; |
||||||
|
b=_b[i]; |
||||||
|
if(a>='a'&&a<='z')a-='a'-'A'; |
||||||
|
if(b>='a'&&b<='z')b-='a'-'A'; |
||||||
|
d=a-b; |
||||||
|
if(d)return d; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,259 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
#if !defined(_opusfile_internal_h) |
||||||
|
# define _opusfile_internal_h (1) |
||||||
|
|
||||||
|
# if !defined(_REENTRANT) |
||||||
|
# define _REENTRANT |
||||||
|
# endif |
||||||
|
# if !defined(_GNU_SOURCE) |
||||||
|
# define _GNU_SOURCE |
||||||
|
# endif |
||||||
|
# if !defined(_LARGEFILE_SOURCE) |
||||||
|
# define _LARGEFILE_SOURCE |
||||||
|
# endif |
||||||
|
# if !defined(_LARGEFILE64_SOURCE) |
||||||
|
# define _LARGEFILE64_SOURCE |
||||||
|
# endif |
||||||
|
# if !defined(_FILE_OFFSET_BITS) |
||||||
|
# define _FILE_OFFSET_BITS 64 |
||||||
|
# endif |
||||||
|
|
||||||
|
# include <stdlib.h> |
||||||
|
# include <opusfile.h> |
||||||
|
|
||||||
|
typedef struct OggOpusLink OggOpusLink; |
||||||
|
|
||||||
|
# if defined(OP_FIXED_POINT) |
||||||
|
|
||||||
|
typedef opus_int16 op_sample; |
||||||
|
|
||||||
|
# else |
||||||
|
|
||||||
|
typedef float op_sample; |
||||||
|
|
||||||
|
/*We're using this define to test for libopus 1.1 or later until libopus
|
||||||
|
provides a better mechanism.*/ |
||||||
|
# if defined(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST) |
||||||
|
/*Enable soft clipping prevention in 16-bit decodes.*/ |
||||||
|
# define OP_SOFT_CLIP (1) |
||||||
|
# endif |
||||||
|
|
||||||
|
# endif |
||||||
|
|
||||||
|
# if OP_GNUC_PREREQ(4,2) |
||||||
|
/*Disable excessive warnings about the order of operations.*/ |
||||||
|
# pragma GCC diagnostic ignored "-Wparentheses" |
||||||
|
# elif defined(_MSC_VER) |
||||||
|
/*Disable excessive warnings about the order of operations.*/ |
||||||
|
# pragma warning(disable:4554) |
||||||
|
/*Disable warnings about "deprecated" POSIX functions.*/ |
||||||
|
# pragma warning(disable:4996) |
||||||
|
# endif |
||||||
|
|
||||||
|
# if OP_GNUC_PREREQ(3,0) |
||||||
|
/*Another alternative is
|
||||||
|
(__builtin_constant_p(_x)?!!(_x):__builtin_expect(!!(_x),1)) |
||||||
|
but that evaluates _x multiple times, which may be bad.*/ |
||||||
|
# define OP_LIKELY(_x) (__builtin_expect(!!(_x),1)) |
||||||
|
# define OP_UNLIKELY(_x) (__builtin_expect(!!(_x),0)) |
||||||
|
# else |
||||||
|
# define OP_LIKELY(_x) (!!(_x)) |
||||||
|
# define OP_UNLIKELY(_x) (!!(_x)) |
||||||
|
# endif |
||||||
|
|
||||||
|
# if defined(OP_ENABLE_ASSERTIONS) |
||||||
|
# if OP_GNUC_PREREQ(2,5)||__SUNPRO_C>=0x590 |
||||||
|
__attribute__((noreturn)) |
||||||
|
# endif |
||||||
|
void op_fatal_impl(const char *_str,const char *_file,int _line); |
||||||
|
|
||||||
|
# define OP_FATAL(_str) (op_fatal_impl(_str,__FILE__,__LINE__)) |
||||||
|
|
||||||
|
# define OP_ASSERT(_cond) \ |
||||||
|
do{ \
|
||||||
|
if(OP_UNLIKELY(!(_cond)))OP_FATAL("assertion failed: " #_cond); \
|
||||||
|
} \
|
||||||
|
while(0) |
||||||
|
# define OP_ALWAYS_TRUE(_cond) OP_ASSERT(_cond) |
||||||
|
|
||||||
|
# else |
||||||
|
# define OP_FATAL(_str) abort() |
||||||
|
# define OP_ASSERT(_cond) |
||||||
|
# define OP_ALWAYS_TRUE(_cond) ((void)(_cond)) |
||||||
|
# endif |
||||||
|
|
||||||
|
# define OP_INT64_MAX (2*(((ogg_int64_t)1<<62)-1)|1) |
||||||
|
# define OP_INT64_MIN (-OP_INT64_MAX-1) |
||||||
|
# define OP_INT32_MAX (2*(((ogg_int32_t)1<<30)-1)|1) |
||||||
|
# define OP_INT32_MIN (-OP_INT32_MAX-1) |
||||||
|
|
||||||
|
# define OP_MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) |
||||||
|
# define OP_MAX(_a,_b) ((_a)>(_b)?(_a):(_b)) |
||||||
|
# define OP_CLAMP(_lo,_x,_hi) (OP_MAX(_lo,OP_MIN(_x,_hi))) |
||||||
|
|
||||||
|
/*Advance a file offset by the given amount, clamping against OP_INT64_MAX.
|
||||||
|
This is used to advance a known offset by things like OP_CHUNK_SIZE or |
||||||
|
OP_PAGE_SIZE_MAX, while making sure to avoid signed overflow. |
||||||
|
It assumes that both _offset and _amount are non-negative.*/ |
||||||
|
#define OP_ADV_OFFSET(_offset,_amount) \ |
||||||
|
(OP_MIN(_offset,OP_INT64_MAX-(_amount))+(_amount)) |
||||||
|
|
||||||
|
/*The maximum channel count for any mapping we'll actually decode.*/ |
||||||
|
# define OP_NCHANNELS_MAX (8) |
||||||
|
|
||||||
|
/*Initial state.*/ |
||||||
|
# define OP_NOTOPEN (0) |
||||||
|
/*We've found the first Opus stream in the first link.*/ |
||||||
|
# define OP_PARTOPEN (1) |
||||||
|
# define OP_OPENED (2) |
||||||
|
/*We've found the first Opus stream in the current link.*/ |
||||||
|
# define OP_STREAMSET (3) |
||||||
|
/*We've initialized the decoder for the chosen Opus stream in the current
|
||||||
|
link.*/ |
||||||
|
# define OP_INITSET (4) |
||||||
|
|
||||||
|
/*Information cached for a single link in a chained Ogg Opus file.
|
||||||
|
We choose the first Opus stream encountered in each link to play back (and |
||||||
|
require at least one).*/ |
||||||
|
struct OggOpusLink{ |
||||||
|
/*The byte offset of the first header page in this link.*/ |
||||||
|
opus_int64 offset; |
||||||
|
/*The byte offset of the first data page from the chosen Opus stream in this
|
||||||
|
link (after the headers).*/ |
||||||
|
opus_int64 data_offset; |
||||||
|
/*The byte offset of the last page from the chosen Opus stream in this link.
|
||||||
|
This is used when seeking to ensure we find a page before the last one, so |
||||||
|
that end-trimming calculations work properly. |
||||||
|
This is only valid for seekable sources.*/ |
||||||
|
opus_int64 end_offset; |
||||||
|
/*The total duration of all prior links.
|
||||||
|
This is always zero for non-seekable sources.*/ |
||||||
|
ogg_int64_t pcm_file_offset; |
||||||
|
/*The granule position of the last sample.
|
||||||
|
This is only valid for seekable sources.*/ |
||||||
|
ogg_int64_t pcm_end; |
||||||
|
/*The granule position before the first sample.*/ |
||||||
|
ogg_int64_t pcm_start; |
||||||
|
/*The serial number.*/ |
||||||
|
ogg_uint32_t serialno; |
||||||
|
/*The contents of the info header.*/ |
||||||
|
OpusHead head; |
||||||
|
/*The contents of the comment header.*/ |
||||||
|
OpusTags tags; |
||||||
|
}; |
||||||
|
|
||||||
|
struct OggOpusFile{ |
||||||
|
/*The callbacks used to access the stream.*/ |
||||||
|
OpusFileCallbacks callbacks; |
||||||
|
/*A FILE *, memory buffer, etc.*/ |
||||||
|
void *stream; |
||||||
|
/*Whether or not we can seek with this stream.*/ |
||||||
|
int seekable; |
||||||
|
/*The number of links in this chained Ogg Opus file.*/ |
||||||
|
int nlinks; |
||||||
|
/*The cached information from each link in a chained Ogg Opus file.
|
||||||
|
If stream isn't seekable (e.g., it's a pipe), only the current link |
||||||
|
appears.*/ |
||||||
|
OggOpusLink *links; |
||||||
|
/*The number of serial numbers from a single link.*/ |
||||||
|
int nserialnos; |
||||||
|
/*The capacity of the list of serial numbers from a single link.*/ |
||||||
|
int cserialnos; |
||||||
|
/*Storage for the list of serial numbers from a single link.
|
||||||
|
This is a scratch buffer used when scanning the BOS pages at the start of |
||||||
|
each link.*/ |
||||||
|
ogg_uint32_t *serialnos; |
||||||
|
/*This is the current offset of the data processed by the ogg_sync_state.
|
||||||
|
After a seek, this should be set to the target offset so that we can track |
||||||
|
the byte offsets of subsequent pages. |
||||||
|
After a call to op_get_next_page(), this will point to the first byte after |
||||||
|
that page.*/ |
||||||
|
opus_int64 offset; |
||||||
|
/*The total size of this stream, or -1 if it's unseekable.*/ |
||||||
|
opus_int64 end; |
||||||
|
/*Used to locate pages in the stream.*/ |
||||||
|
ogg_sync_state oy; |
||||||
|
/*One of OP_NOTOPEN, OP_PARTOPEN, OP_OPENED, OP_STREAMSET, OP_INITSET.*/ |
||||||
|
int ready_state; |
||||||
|
/*The current link being played back.*/ |
||||||
|
int cur_link; |
||||||
|
/*The number of decoded samples to discard from the start of decoding.*/ |
||||||
|
opus_int32 cur_discard_count; |
||||||
|
/*The granule position of the previous packet (current packet start time).*/ |
||||||
|
ogg_int64_t prev_packet_gp; |
||||||
|
/*The stream offset of the most recent page with completed packets, or -1.
|
||||||
|
This is only needed to recover continued packet data in the seeking logic, |
||||||
|
when we use the current position as one of our bounds, only to later |
||||||
|
discover it was the correct starting point.*/ |
||||||
|
opus_int64 prev_page_offset; |
||||||
|
/*The number of bytes read since the last bitrate query, including framing.*/ |
||||||
|
opus_int64 bytes_tracked; |
||||||
|
/*The number of samples decoded since the last bitrate query.*/ |
||||||
|
ogg_int64_t samples_tracked; |
||||||
|
/*Takes physical pages and welds them into a logical stream of packets.*/ |
||||||
|
ogg_stream_state os; |
||||||
|
/*Re-timestamped packets from a single page.
|
||||||
|
Buffering these relies on the undocumented libogg behavior that ogg_packet |
||||||
|
pointers remain valid until the next page is submitted to the |
||||||
|
ogg_stream_state they came from.*/ |
||||||
|
ogg_packet op[255]; |
||||||
|
/*The index of the next packet to return.*/ |
||||||
|
int op_pos; |
||||||
|
/*The total number of packets available.*/ |
||||||
|
int op_count; |
||||||
|
/*Central working state for the packet-to-PCM decoder.*/ |
||||||
|
OpusMSDecoder *od; |
||||||
|
/*The application-provided packet decode callback.*/ |
||||||
|
op_decode_cb_func decode_cb; |
||||||
|
/*The application-provided packet decode callback context.*/ |
||||||
|
void *decode_cb_ctx; |
||||||
|
/*The stream count used to initialize the decoder.*/ |
||||||
|
int od_stream_count; |
||||||
|
/*The coupled stream count used to initialize the decoder.*/ |
||||||
|
int od_coupled_count; |
||||||
|
/*The channel count used to initialize the decoder.*/ |
||||||
|
int od_channel_count; |
||||||
|
/*The channel mapping used to initialize the decoder.*/ |
||||||
|
unsigned char od_mapping[OP_NCHANNELS_MAX]; |
||||||
|
/*The buffered data for one decoded packet.*/ |
||||||
|
op_sample *od_buffer; |
||||||
|
/*The current position in the decoded buffer.*/ |
||||||
|
int od_buffer_pos; |
||||||
|
/*The number of valid samples in the decoded buffer.*/ |
||||||
|
int od_buffer_size; |
||||||
|
/*The type of gain offset to apply.
|
||||||
|
One of OP_HEADER_GAIN, OP_ALBUM_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.*/ |
||||||
|
int gain_type; |
||||||
|
/*The offset to apply to the gain.*/ |
||||||
|
opus_int32 gain_offset_q8; |
||||||
|
/*Internal state for soft clipping and dithering float->short output.*/ |
||||||
|
#if !defined(OP_FIXED_POINT) |
||||||
|
# if defined(OP_SOFT_CLIP) |
||||||
|
float clip_state[OP_NCHANNELS_MAX]; |
||||||
|
# endif |
||||||
|
float dither_a[OP_NCHANNELS_MAX*4]; |
||||||
|
float dither_b[OP_NCHANNELS_MAX*4]; |
||||||
|
opus_uint32 dither_seed; |
||||||
|
int dither_mute; |
||||||
|
int dither_disabled; |
||||||
|
/*The number of channels represented by the internal state.
|
||||||
|
This gets set to 0 whenever anything that would prevent state propagation |
||||||
|
occurs (switching between the float/short APIs, or between the |
||||||
|
stereo/multistream APIs).*/ |
||||||
|
int state_channel_count; |
||||||
|
#endif |
||||||
|
}; |
||||||
|
|
||||||
|
int op_strncasecmp(const char *_a,const char *_b,int _n); |
||||||
|
|
||||||
|
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,415 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2018 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
******************************************************************** |
||||||
|
|
||||||
|
function: stdio-based convenience library for opening/seeking/decoding |
||||||
|
last mod: $Id: vorbisfile.c 17573 2010-10-27 14:53:59Z xiphmont $ |
||||||
|
|
||||||
|
********************************************************************/ |
||||||
|
#ifdef HAVE_CONFIG_H |
||||||
|
#include "config.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "internal.h" |
||||||
|
#include <sys/types.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <errno.h> |
||||||
|
#include <string.h> |
||||||
|
#if defined(_WIN32) |
||||||
|
# include <io.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef struct OpusMemStream OpusMemStream; |
||||||
|
|
||||||
|
#define OP_MEM_SIZE_MAX (~(size_t)0>>1) |
||||||
|
#define OP_MEM_DIFF_MAX ((ptrdiff_t)OP_MEM_SIZE_MAX) |
||||||
|
|
||||||
|
/*The context information needed to read from a block of memory as if it were a
|
||||||
|
file.*/ |
||||||
|
struct OpusMemStream{ |
||||||
|
/*The block of memory to read from.*/ |
||||||
|
const unsigned char *data; |
||||||
|
/*The total size of the block.
|
||||||
|
This must be at most OP_MEM_SIZE_MAX to prevent signed overflow while |
||||||
|
seeking.*/ |
||||||
|
ptrdiff_t size; |
||||||
|
/*The current file position.
|
||||||
|
This is allowed to be set arbitrarily greater than size (i.e., past the end |
||||||
|
of the block, though we will not read data past the end of the block), but |
||||||
|
is not allowed to be negative (i.e., before the beginning of the block).*/ |
||||||
|
ptrdiff_t pos; |
||||||
|
}; |
||||||
|
|
||||||
|
static int op_fread(void *_stream,unsigned char *_ptr,int _buf_size){ |
||||||
|
FILE *stream; |
||||||
|
size_t ret; |
||||||
|
/*Check for empty read.*/ |
||||||
|
if(_buf_size<=0)return 0; |
||||||
|
stream=(FILE *)_stream; |
||||||
|
ret=fread(_ptr,1,_buf_size,stream); |
||||||
|
OP_ASSERT(ret<=(size_t)_buf_size); |
||||||
|
/*If ret==0 and !feof(stream), there was a read error.*/ |
||||||
|
return ret>0||feof(stream)?(int)ret:OP_EREAD; |
||||||
|
} |
||||||
|
|
||||||
|
static int op_fseek(void *_stream,opus_int64 _offset,int _whence){ |
||||||
|
#if defined(_WIN32) |
||||||
|
/*_fseeki64() is not exposed until MSVCRT80.
|
||||||
|
This is the default starting with MSVC 2005 (_MSC_VER>=1400), but we want |
||||||
|
to allow linking against older MSVCRT versions for compatibility back to |
||||||
|
XP without installing extra runtime libraries. |
||||||
|
i686-pc-mingw32 does not have fseeko() and requires |
||||||
|
__MSVCRT_VERSION__>=0x800 for _fseeki64(), which screws up linking with |
||||||
|
other libraries (that don't use MSVCRT80 from MSVC 2005 by default). |
||||||
|
i686-w64-mingw32 does have fseeko() and respects _FILE_OFFSET_BITS, but I |
||||||
|
don't know how to detect that at compile time. |
||||||
|
We could just use fseeko64() (which is available in both), but it's |
||||||
|
implemented using fgetpos()/fsetpos() just like this code, except without |
||||||
|
the overflow checking, so we prefer our version.*/ |
||||||
|
opus_int64 pos; |
||||||
|
/*We don't use fpos_t directly because it might be a struct if __STDC__ is
|
||||||
|
non-zero or _INTEGRAL_MAX_BITS < 64. |
||||||
|
I'm not certain when the latter is true, but someone could in theory set |
||||||
|
the former. |
||||||
|
Either way, it should be binary compatible with a normal 64-bit int (this |
||||||
|
assumption is not portable, but I believe it is true for MSVCRT).*/ |
||||||
|
OP_ASSERT(sizeof(pos)==sizeof(fpos_t)); |
||||||
|
/*Translate the seek to an absolute one.*/ |
||||||
|
if(_whence==SEEK_CUR){ |
||||||
|
int ret; |
||||||
|
ret=fgetpos((FILE *)_stream,(fpos_t *)&pos); |
||||||
|
if(ret)return ret; |
||||||
|
} |
||||||
|
else if(_whence==SEEK_END)pos=_filelengthi64(_fileno((FILE *)_stream)); |
||||||
|
else if(_whence==SEEK_SET)pos=0; |
||||||
|
else return -1; |
||||||
|
/*Check for errors or overflow.*/ |
||||||
|
if(pos<0||_offset<-pos||_offset>OP_INT64_MAX-pos)return -1; |
||||||
|
pos+=_offset; |
||||||
|
return fsetpos((FILE *)_stream,(fpos_t *)&pos); |
||||||
|
#else |
||||||
|
/*This function actually conforms to the SUSv2 and POSIX.1-2001, so we prefer
|
||||||
|
it except on Windows.*/ |
||||||
|
return fseeko((FILE *)_stream,(off_t)_offset,_whence); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
static opus_int64 op_ftell(void *_stream){ |
||||||
|
#if defined(_WIN32) |
||||||
|
/*_ftelli64() is not exposed until MSVCRT80, and ftello()/ftello64() have
|
||||||
|
the same problems as fseeko()/fseeko64() in MingW. |
||||||
|
See above for a more detailed explanation.*/ |
||||||
|
opus_int64 pos; |
||||||
|
OP_ASSERT(sizeof(pos)==sizeof(fpos_t)); |
||||||
|
return fgetpos((FILE *)_stream,(fpos_t *)&pos)?-1:pos; |
||||||
|
#else |
||||||
|
/*This function actually conforms to the SUSv2 and POSIX.1-2001, so we prefer
|
||||||
|
it except on Windows.*/ |
||||||
|
return ftello((FILE *)_stream); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
static const OpusFileCallbacks OP_FILE_CALLBACKS={ |
||||||
|
op_fread, |
||||||
|
op_fseek, |
||||||
|
op_ftell, |
||||||
|
(op_close_func)fclose |
||||||
|
}; |
||||||
|
|
||||||
|
#if defined(_WIN32) |
||||||
|
# include <stddef.h> |
||||||
|
# include <errno.h> |
||||||
|
|
||||||
|
/*Windows doesn't accept UTF-8 by default, and we don't have a wchar_t API,
|
||||||
|
so if we just pass the path to fopen(), then there'd be no way for a user |
||||||
|
of our API to open a Unicode filename. |
||||||
|
Instead, we translate from UTF-8 to UTF-16 and use Windows' wchar_t API. |
||||||
|
This makes this API more consistent with platforms where the character set |
||||||
|
used by fopen is the same as used on disk, which is generally UTF-8, and |
||||||
|
with our metadata API, which always uses UTF-8.*/ |
||||||
|
static wchar_t *op_utf8_to_utf16(const char *_src){ |
||||||
|
wchar_t *dst; |
||||||
|
size_t len; |
||||||
|
len=strlen(_src); |
||||||
|
/*Worst-case output is 1 wide character per 1 input character.*/ |
||||||
|
dst=(wchar_t *)_ogg_malloc(sizeof(*dst)*(len+1)); |
||||||
|
if(dst!=NULL){ |
||||||
|
size_t si; |
||||||
|
size_t di; |
||||||
|
for(di=si=0;si<len;si++){ |
||||||
|
int c0; |
||||||
|
c0=(unsigned char)_src[si]; |
||||||
|
if(!(c0&0x80)){ |
||||||
|
/*Start byte says this is a 1-byte sequence.*/ |
||||||
|
dst[di++]=(wchar_t)c0; |
||||||
|
continue; |
||||||
|
} |
||||||
|
else{ |
||||||
|
int c1; |
||||||
|
/*This is safe, because c0 was not 0 and _src is NUL-terminated.*/ |
||||||
|
c1=(unsigned char)_src[si+1]; |
||||||
|
if((c1&0xC0)==0x80){ |
||||||
|
/*Found at least one continuation byte.*/ |
||||||
|
if((c0&0xE0)==0xC0){ |
||||||
|
wchar_t w; |
||||||
|
/*Start byte says this is a 2-byte sequence.*/ |
||||||
|
w=(c0&0x1F)<<6|c1&0x3F; |
||||||
|
if(w>=0x80U){ |
||||||
|
/*This is a 2-byte sequence that is not overlong.*/ |
||||||
|
dst[di++]=w; |
||||||
|
si++; |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
else{ |
||||||
|
int c2; |
||||||
|
/*This is safe, because c1 was not 0 and _src is NUL-terminated.*/ |
||||||
|
c2=(unsigned char)_src[si+2]; |
||||||
|
if((c2&0xC0)==0x80){ |
||||||
|
/*Found at least two continuation bytes.*/ |
||||||
|
if((c0&0xF0)==0xE0){ |
||||||
|
wchar_t w; |
||||||
|
/*Start byte says this is a 3-byte sequence.*/ |
||||||
|
w=(c0&0xF)<<12|(c1&0x3F)<<6|c2&0x3F; |
||||||
|
if(w>=0x800U&&(w<0xD800||w>=0xE000)&&w<0xFFFE){ |
||||||
|
/*This is a 3-byte sequence that is not overlong, not a
|
||||||
|
UTF-16 surrogate pair value, and not a 'not a character' |
||||||
|
value.*/ |
||||||
|
dst[di++]=w; |
||||||
|
si+=2; |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
else{ |
||||||
|
int c3; |
||||||
|
/*This is safe, because c2 was not 0 and _src is
|
||||||
|
NUL-terminated.*/ |
||||||
|
c3=(unsigned char)_src[si+3]; |
||||||
|
if((c3&0xC0)==0x80){ |
||||||
|
/*Found at least three continuation bytes.*/ |
||||||
|
if((c0&0xF8)==0xF0){ |
||||||
|
opus_uint32 w; |
||||||
|
/*Start byte says this is a 4-byte sequence.*/ |
||||||
|
w=(c0&7)<<18|(c1&0x3F)<<12|(c2&0x3F)<<6&(c3&0x3F); |
||||||
|
if(w>=0x10000U&&w<0x110000U){ |
||||||
|
/*This is a 4-byte sequence that is not overlong and not
|
||||||
|
greater than the largest valid Unicode code point. |
||||||
|
Convert it to a surrogate pair.*/ |
||||||
|
w-=0x10000; |
||||||
|
dst[di++]=(wchar_t)(0xD800+(w>>10)); |
||||||
|
dst[di++]=(wchar_t)(0xDC00+(w&0x3FF)); |
||||||
|
si+=3; |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
/*If we got here, we encountered an illegal UTF-8 sequence.*/ |
||||||
|
_ogg_free(dst); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
OP_ASSERT(di<=len); |
||||||
|
dst[di]='\0'; |
||||||
|
} |
||||||
|
return dst; |
||||||
|
} |
||||||
|
|
||||||
|
/*fsetpos() internally dispatches to the win32 API call SetFilePointer().
|
||||||
|
According to SetFilePointer()'s documentation [0], the behavior is |
||||||
|
undefined if you do not call it on "a file stored on a seeking device". |
||||||
|
However, none of the MSVCRT seeking functions verify what kind of file is |
||||||
|
being used before calling it (which I believe is a bug, since they are |
||||||
|
supposed to fail and return an error, but it is a bug that has been there |
||||||
|
for multiple decades now). |
||||||
|
In practice, SetFilePointer() appears to succeed for things like stdin, |
||||||
|
even when you are not just piping in a regular file, which prevents the use |
||||||
|
of this API to determine whether it is possible to seek in a file at all. |
||||||
|
Therefore, we take the approach recommended by the SetFilePointer() |
||||||
|
documentation and confirm the type of file using GetFileType() first. |
||||||
|
We do this once, when the file is opened, and return the corresponding |
||||||
|
callback in order to avoid an extra win32 API call on every seek in the |
||||||
|
common case. |
||||||
|
Hopefully the return value of GetFileType() cannot actually change for the |
||||||
|
lifetime of a file handle. |
||||||
|
[0] https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-setfilepointer
|
||||||
|
*/ |
||||||
|
static int op_fseek_fail(void *_stream,opus_int64 _offset,int _whence){ |
||||||
|
(void)_stream; |
||||||
|
(void)_offset; |
||||||
|
(void)_whence; |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
static const OpusFileCallbacks OP_UNSEEKABLE_FILE_CALLBACKS={ |
||||||
|
op_fread, |
||||||
|
op_fseek_fail, |
||||||
|
op_ftell, |
||||||
|
(op_close_func)fclose |
||||||
|
}; |
||||||
|
|
||||||
|
# define WIN32_LEAN_AND_MEAN |
||||||
|
# define WIN32_EXTRA_LEAN |
||||||
|
# include <windows.h> |
||||||
|
|
||||||
|
static const OpusFileCallbacks *op_get_file_callbacks(FILE *_fp){ |
||||||
|
intptr_t h_file; |
||||||
|
h_file=_get_osfhandle(_fileno(_fp)); |
||||||
|
if(h_file!=-1 |
||||||
|
&&(GetFileType((HANDLE)h_file)&~FILE_TYPE_REMOTE)==FILE_TYPE_DISK){ |
||||||
|
return &OP_FILE_CALLBACKS; |
||||||
|
} |
||||||
|
return &OP_UNSEEKABLE_FILE_CALLBACKS; |
||||||
|
} |
||||||
|
#else |
||||||
|
static const OpusFileCallbacks *op_get_file_callbacks(FILE *_fp){ |
||||||
|
(void)_fp; |
||||||
|
return &OP_FILE_CALLBACKS; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
void *op_fopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode){ |
||||||
|
FILE *fp; |
||||||
|
#if !defined(_WIN32) |
||||||
|
fp=fopen(_path,_mode); |
||||||
|
#else |
||||||
|
fp=NULL; |
||||||
|
{ |
||||||
|
wchar_t *wpath; |
||||||
|
wchar_t *wmode; |
||||||
|
wpath=op_utf8_to_utf16(_path); |
||||||
|
wmode=op_utf8_to_utf16(_mode); |
||||||
|
if(wmode==NULL)errno=EINVAL; |
||||||
|
else if(wpath==NULL)errno=ENOENT; |
||||||
|
else fp=_wfopen(wpath,wmode); |
||||||
|
_ogg_free(wmode); |
||||||
|
_ogg_free(wpath); |
||||||
|
} |
||||||
|
#endif |
||||||
|
if(fp!=NULL)*_cb=*op_get_file_callbacks(fp); |
||||||
|
return fp; |
||||||
|
} |
||||||
|
|
||||||
|
void *op_fdopen(OpusFileCallbacks *_cb,int _fd,const char *_mode){ |
||||||
|
FILE *fp; |
||||||
|
fp=fdopen(_fd,_mode); |
||||||
|
if(fp!=NULL)*_cb=*op_get_file_callbacks(fp); |
||||||
|
return fp; |
||||||
|
} |
||||||
|
|
||||||
|
void *op_freopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode, |
||||||
|
void *_stream){ |
||||||
|
FILE *fp; |
||||||
|
#if !defined(_WIN32) |
||||||
|
fp=freopen(_path,_mode,(FILE *)_stream); |
||||||
|
#else |
||||||
|
fp=NULL; |
||||||
|
{ |
||||||
|
wchar_t *wpath; |
||||||
|
wchar_t *wmode; |
||||||
|
wpath=op_utf8_to_utf16(_path); |
||||||
|
wmode=op_utf8_to_utf16(_mode); |
||||||
|
if(wmode==NULL)errno=EINVAL; |
||||||
|
else if(wpath==NULL)errno=ENOENT; |
||||||
|
else fp=_wfreopen(wpath,wmode,(FILE *)_stream); |
||||||
|
_ogg_free(wmode); |
||||||
|
_ogg_free(wpath); |
||||||
|
} |
||||||
|
#endif |
||||||
|
if(fp!=NULL)*_cb=*op_get_file_callbacks(fp); |
||||||
|
return fp; |
||||||
|
} |
||||||
|
|
||||||
|
static int op_mem_read(void *_stream,unsigned char *_ptr,int _buf_size){ |
||||||
|
OpusMemStream *stream; |
||||||
|
ptrdiff_t size; |
||||||
|
ptrdiff_t pos; |
||||||
|
stream=(OpusMemStream *)_stream; |
||||||
|
/*Check for empty read.*/ |
||||||
|
if(_buf_size<=0)return 0; |
||||||
|
size=stream->size; |
||||||
|
pos=stream->pos; |
||||||
|
/*Check for EOF.*/ |
||||||
|
if(pos>=size)return 0; |
||||||
|
/*Check for a short read.*/ |
||||||
|
_buf_size=(int)OP_MIN(size-pos,_buf_size); |
||||||
|
memcpy(_ptr,stream->data+pos,_buf_size); |
||||||
|
pos+=_buf_size; |
||||||
|
stream->pos=pos; |
||||||
|
return _buf_size; |
||||||
|
} |
||||||
|
|
||||||
|
static int op_mem_seek(void *_stream,opus_int64 _offset,int _whence){ |
||||||
|
OpusMemStream *stream; |
||||||
|
ptrdiff_t pos; |
||||||
|
stream=(OpusMemStream *)_stream; |
||||||
|
pos=stream->pos; |
||||||
|
OP_ASSERT(pos>=0); |
||||||
|
switch(_whence){ |
||||||
|
case SEEK_SET:{ |
||||||
|
/*Check for overflow:*/ |
||||||
|
if(_offset<0||_offset>OP_MEM_DIFF_MAX)return -1; |
||||||
|
pos=(ptrdiff_t)_offset; |
||||||
|
}break; |
||||||
|
case SEEK_CUR:{ |
||||||
|
/*Check for overflow:*/ |
||||||
|
if(_offset<-pos||_offset>OP_MEM_DIFF_MAX-pos)return -1; |
||||||
|
pos=(ptrdiff_t)(pos+_offset); |
||||||
|
}break; |
||||||
|
case SEEK_END:{ |
||||||
|
ptrdiff_t size; |
||||||
|
size=stream->size; |
||||||
|
OP_ASSERT(size>=0); |
||||||
|
/*Check for overflow:*/ |
||||||
|
if(_offset<-size||_offset>OP_MEM_DIFF_MAX-size)return -1; |
||||||
|
pos=(ptrdiff_t)(size+_offset); |
||||||
|
}break; |
||||||
|
default:return -1; |
||||||
|
} |
||||||
|
stream->pos=pos; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static opus_int64 op_mem_tell(void *_stream){ |
||||||
|
OpusMemStream *stream; |
||||||
|
stream=(OpusMemStream *)_stream; |
||||||
|
return (ogg_int64_t)stream->pos; |
||||||
|
} |
||||||
|
|
||||||
|
static int op_mem_close(void *_stream){ |
||||||
|
_ogg_free(_stream); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static const OpusFileCallbacks OP_MEM_CALLBACKS={ |
||||||
|
op_mem_read, |
||||||
|
op_mem_seek, |
||||||
|
op_mem_tell, |
||||||
|
op_mem_close |
||||||
|
}; |
||||||
|
|
||||||
|
void *op_mem_stream_create(OpusFileCallbacks *_cb, |
||||||
|
const unsigned char *_data,size_t _size){ |
||||||
|
OpusMemStream *stream; |
||||||
|
if(_size>OP_MEM_SIZE_MAX)return NULL; |
||||||
|
stream=(OpusMemStream *)_ogg_malloc(sizeof(*stream)); |
||||||
|
if(stream!=NULL){ |
||||||
|
*_cb=*&OP_MEM_CALLBACKS; |
||||||
|
stream->data=_data; |
||||||
|
stream->size=_size; |
||||||
|
stream->pos=0; |
||||||
|
} |
||||||
|
return stream; |
||||||
|
} |
@ -0,0 +1,173 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2013-2016 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
|
||||||
|
/*This should really be part of OpenSSL, but there's been a patch [1] sitting
|
||||||
|
in their bugtracker for over two years that implements this, without any |
||||||
|
action, so I'm giving up and re-implementing it locally. |
||||||
|
|
||||||
|
[1] <https://rt.openssl.org/Ticket/Display.html?id=2158>*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H |
||||||
|
#include "config.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "internal.h" |
||||||
|
#if defined(OP_ENABLE_HTTP)&&defined(_WIN32) |
||||||
|
/*You must include windows.h before wincrypt.h and x509.h.*/ |
||||||
|
# define WIN32_LEAN_AND_MEAN |
||||||
|
# define WIN32_EXTRA_LEAN |
||||||
|
# include <windows.h> |
||||||
|
/*You must include wincrypt.h before x509.h, too, or X509_NAME doesn't get
|
||||||
|
defined properly.*/ |
||||||
|
# include <wincrypt.h> |
||||||
|
# include <openssl/ssl.h> |
||||||
|
# include <openssl/err.h> |
||||||
|
# include <openssl/x509.h> |
||||||
|
|
||||||
|
static int op_capi_new(X509_LOOKUP *_lu){ |
||||||
|
HCERTSTORE h_store; |
||||||
|
h_store=CertOpenStore(CERT_STORE_PROV_SYSTEM_A,0,0, |
||||||
|
CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG| |
||||||
|
CERT_SYSTEM_STORE_CURRENT_USER|CERT_STORE_SHARE_CONTEXT_FLAG,"ROOT"); |
||||||
|
if(h_store!=NULL){ |
||||||
|
_lu->method_data=(char *)h_store; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static void op_capi_free(X509_LOOKUP *_lu){ |
||||||
|
HCERTSTORE h_store; |
||||||
|
h_store=(HCERTSTORE)_lu->method_data; |
||||||
|
# if defined(OP_ENABLE_ASSERTIONS) |
||||||
|
OP_ALWAYS_TRUE(CertCloseStore(h_store,CERT_CLOSE_STORE_CHECK_FLAG)); |
||||||
|
# else |
||||||
|
CertCloseStore(h_store,0); |
||||||
|
# endif |
||||||
|
} |
||||||
|
|
||||||
|
static int op_capi_retrieve_by_subject(X509_LOOKUP *_lu,int _type, |
||||||
|
X509_NAME *_name,X509_OBJECT *_ret){ |
||||||
|
X509_OBJECT *obj; |
||||||
|
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
||||||
|
obj=X509_OBJECT_retrieve_by_subject(_lu->store_ctx->objs,_type,_name); |
||||||
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
||||||
|
if(obj!=NULL){ |
||||||
|
_ret->type=obj->type; |
||||||
|
memcpy(&_ret->data,&obj->data,sizeof(_ret->data)); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name, |
||||||
|
X509_OBJECT *_ret){ |
||||||
|
HCERTSTORE h_store; |
||||||
|
if(_name==NULL)return 0; |
||||||
|
if(_name->bytes==NULL||_name->bytes->length<=0||_name->modified){ |
||||||
|
if(i2d_X509_NAME(_name,NULL)<0)return 0; |
||||||
|
OP_ASSERT(_name->bytes->length>0); |
||||||
|
} |
||||||
|
h_store=(HCERTSTORE)_lu->method_data; |
||||||
|
switch(_type){ |
||||||
|
case X509_LU_X509:{ |
||||||
|
CERT_NAME_BLOB find_para; |
||||||
|
PCCERT_CONTEXT cert; |
||||||
|
X509 *x; |
||||||
|
int ret; |
||||||
|
/*Although X509_NAME contains a canon_enc field, that "canonical" [1]
|
||||||
|
encoding was just made up by OpenSSL. |
||||||
|
It doesn't correspond to any actual standard, and since it drops the |
||||||
|
initial sequence header, won't be recognized by the Crypto API. |
||||||
|
The assumption here is that CertFindCertificateInStore() will allow any |
||||||
|
appropriate variations in the encoding when it does its comparison. |
||||||
|
This is, however, emphatically not true under Wine, which just compares |
||||||
|
the encodings with memcmp(). |
||||||
|
Most of the time things work anyway, though, and there isn't really |
||||||
|
anything we can do to make the situation better. |
||||||
|
|
||||||
|
[1] A "canonical form" is defined as the one where, if you locked 10 |
||||||
|
mathematicians in a room and asked them to come up with a |
||||||
|
representation for something, it's the answer that 9 of them would |
||||||
|
give you back. |
||||||
|
I don't think OpenSSL's encoding qualifies.*/ |
||||||
|
if(OP_UNLIKELY(_name->bytes->length>MAXDWORD))return 0; |
||||||
|
find_para.cbData=(DWORD)_name->bytes->length; |
||||||
|
find_para.pbData=(unsigned char *)_name->bytes->data; |
||||||
|
cert=CertFindCertificateInStore(h_store,X509_ASN_ENCODING,0, |
||||||
|
CERT_FIND_SUBJECT_NAME,&find_para,NULL); |
||||||
|
if(cert==NULL)return 0; |
||||||
|
x=d2i_X509(NULL,(const unsigned char **)&cert->pbCertEncoded, |
||||||
|
cert->cbCertEncoded); |
||||||
|
CertFreeCertificateContext(cert); |
||||||
|
if(x==NULL)return 0; |
||||||
|
ret=X509_STORE_add_cert(_lu->store_ctx,x); |
||||||
|
X509_free(x); |
||||||
|
if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret); |
||||||
|
}break; |
||||||
|
case X509_LU_CRL:{ |
||||||
|
CERT_INFO cert_info; |
||||||
|
CERT_CONTEXT find_para; |
||||||
|
PCCRL_CONTEXT crl; |
||||||
|
X509_CRL *x; |
||||||
|
int ret; |
||||||
|
ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret); |
||||||
|
if(ret>0)return ret; |
||||||
|
memset(&cert_info,0,sizeof(cert_info)); |
||||||
|
if(OP_UNLIKELY(_name->bytes->length>MAXDWORD))return 0; |
||||||
|
cert_info.Issuer.cbData=(DWORD)_name->bytes->length; |
||||||
|
cert_info.Issuer.pbData=(unsigned char *)_name->bytes->data; |
||||||
|
memset(&find_para,0,sizeof(find_para)); |
||||||
|
find_para.pCertInfo=&cert_info; |
||||||
|
crl=CertFindCRLInStore(h_store,0,0,CRL_FIND_ISSUED_BY,&find_para,NULL); |
||||||
|
if(crl==NULL)return 0; |
||||||
|
x=d2i_X509_CRL(NULL,(const unsigned char **)&crl->pbCrlEncoded, |
||||||
|
crl->cbCrlEncoded); |
||||||
|
CertFreeCRLContext(crl); |
||||||
|
if(x==NULL)return 0; |
||||||
|
ret=X509_STORE_add_crl(_lu->store_ctx,x); |
||||||
|
X509_CRL_free(x); |
||||||
|
if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret); |
||||||
|
}break; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*This is not const because OpenSSL doesn't allow it, even though it won't
|
||||||
|
write to it.*/ |
||||||
|
static X509_LOOKUP_METHOD X509_LOOKUP_CAPI={ |
||||||
|
"Load Crypto API store into cache", |
||||||
|
op_capi_new, |
||||||
|
op_capi_free, |
||||||
|
NULL, |
||||||
|
NULL, |
||||||
|
NULL, |
||||||
|
op_capi_get_by_subject, |
||||||
|
NULL, |
||||||
|
NULL, |
||||||
|
NULL |
||||||
|
}; |
||||||
|
|
||||||
|
int SSL_CTX_set_default_verify_paths_win32(SSL_CTX *_ssl_ctx){ |
||||||
|
X509_STORE *store; |
||||||
|
X509_LOOKUP *lu; |
||||||
|
/*We intentionally do not add the normal default paths, as they are usually
|
||||||
|
wrong, and are just asking to be used as an exploit vector.*/ |
||||||
|
store=SSL_CTX_get_cert_store(_ssl_ctx); |
||||||
|
OP_ASSERT(store!=NULL); |
||||||
|
lu=X509_STORE_add_lookup(store,&X509_LOOKUP_CAPI); |
||||||
|
if(lu==NULL)return 0; |
||||||
|
ERR_clear_error(); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,90 @@ |
|||||||
|
/********************************************************************
|
||||||
|
* * |
||||||
|
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * |
||||||
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||||||
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||||||
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||||||
|
* * |
||||||
|
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2013 * |
||||||
|
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||||
|
* * |
||||||
|
********************************************************************/ |
||||||
|
#if !defined(_opusfile_winerrno_h) |
||||||
|
# define _opusfile_winerrno_h (1) |
||||||
|
|
||||||
|
# include <errno.h> |
||||||
|
# include <winerror.h> |
||||||
|
|
||||||
|
/*These conflict with the MSVC errno.h definitions, but we don't need to use
|
||||||
|
the original ones in any file that deals with sockets. |
||||||
|
We could map the WSA errors to the errno.h ones (most of which are only |
||||||
|
available on sufficiently new versions of MSVC), but they aren't ordered the |
||||||
|
same, and given how rarely we actually look at the values, I don't think |
||||||
|
it's worth a lookup table.*/ |
||||||
|
# undef EWOULDBLOCK |
||||||
|
# undef EINPROGRESS |
||||||
|
# undef EALREADY |
||||||
|
# undef ENOTSOCK |
||||||
|
# undef EDESTADDRREQ |
||||||
|
# undef EMSGSIZE |
||||||
|
# undef EPROTOTYPE |
||||||
|
# undef ENOPROTOOPT |
||||||
|
# undef EPROTONOSUPPORT |
||||||
|
# undef EOPNOTSUPP |
||||||
|
# undef EAFNOSUPPORT |
||||||
|
# undef EADDRINUSE |
||||||
|
# undef EADDRNOTAVAIL |
||||||
|
# undef ENETDOWN |
||||||
|
# undef ENETUNREACH |
||||||
|
# undef ENETRESET |
||||||
|
# undef ECONNABORTED |
||||||
|
# undef ECONNRESET |
||||||
|
# undef ENOBUFS |
||||||
|
# undef EISCONN |
||||||
|
# undef ENOTCONN |
||||||
|
# undef ETIMEDOUT |
||||||
|
# undef ECONNREFUSED |
||||||
|
# undef ELOOP |
||||||
|
# undef ENAMETOOLONG |
||||||
|
# undef EHOSTUNREACH |
||||||
|
# undef ENOTEMPTY |
||||||
|
|
||||||
|
# define EWOULDBLOCK (WSAEWOULDBLOCK-WSABASEERR) |
||||||
|
# define EINPROGRESS (WSAEINPROGRESS-WSABASEERR) |
||||||
|
# define EALREADY (WSAEALREADY-WSABASEERR) |
||||||
|
# define ENOTSOCK (WSAENOTSOCK-WSABASEERR) |
||||||
|
# define EDESTADDRREQ (WSAEDESTADDRREQ-WSABASEERR) |
||||||
|
# define EMSGSIZE (WSAEMSGSIZE-WSABASEERR) |
||||||
|
# define EPROTOTYPE (WSAEPROTOTYPE-WSABASEERR) |
||||||
|
# define ENOPROTOOPT (WSAENOPROTOOPT-WSABASEERR) |
||||||
|
# define EPROTONOSUPPORT (WSAEPROTONOSUPPORT-WSABASEERR) |
||||||
|
# define ESOCKTNOSUPPORT (WSAESOCKTNOSUPPORT-WSABASEERR) |
||||||
|
# define EOPNOTSUPP (WSAEOPNOTSUPP-WSABASEERR) |
||||||
|
# define EPFNOSUPPORT (WSAEPFNOSUPPORT-WSABASEERR) |
||||||
|
# define EAFNOSUPPORT (WSAEAFNOSUPPORT-WSABASEERR) |
||||||
|
# define EADDRINUSE (WSAEADDRINUSE-WSABASEERR) |
||||||
|
# define EADDRNOTAVAIL (WSAEADDRNOTAVAIL-WSABASEERR) |
||||||
|
# define ENETDOWN (WSAENETDOWN-WSABASEERR) |
||||||
|
# define ENETUNREACH (WSAENETUNREACH-WSABASEERR) |
||||||
|
# define ENETRESET (WSAENETRESET-WSABASEERR) |
||||||
|
# define ECONNABORTED (WSAECONNABORTED-WSABASEERR) |
||||||
|
# define ECONNRESET (WSAECONNRESET-WSABASEERR) |
||||||
|
# define ENOBUFS (WSAENOBUFS-WSABASEERR) |
||||||
|
# define EISCONN (WSAEISCONN-WSABASEERR) |
||||||
|
# define ENOTCONN (WSAENOTCONN-WSABASEERR) |
||||||
|
# define ESHUTDOWN (WSAESHUTDOWN-WSABASEERR) |
||||||
|
# define ETOOMANYREFS (WSAETOOMANYREFS-WSABASEERR) |
||||||
|
# define ETIMEDOUT (WSAETIMEDOUT-WSABASEERR) |
||||||
|
# define ECONNREFUSED (WSAECONNREFUSED-WSABASEERR) |
||||||
|
# define ELOOP (WSAELOOP-WSABASEERR) |
||||||
|
# define ENAMETOOLONG (WSAENAMETOOLONG-WSABASEERR) |
||||||
|
# define EHOSTDOWN (WSAEHOSTDOWN-WSABASEERR) |
||||||
|
# define EHOSTUNREACH (WSAEHOSTUNREACH-WSABASEERR) |
||||||
|
# define ENOTEMPTY (WSAENOTEMPTY-WSABASEERR) |
||||||
|
# define EPROCLIM (WSAEPROCLIM-WSABASEERR) |
||||||
|
# define EUSERS (WSAEUSERS-WSABASEERR) |
||||||
|
# define EDQUOT (WSAEDQUOT-WSABASEERR) |
||||||
|
# define ESTALE (WSAESTALE-WSABASEERR) |
||||||
|
# define EREMOTE (WSAEREMOTE-WSABASEERR) |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,243 @@ |
|||||||
|
# NOTE: This Makefile requires GNU make
|
||||||
|
# Location to put the targets.
|
||||||
|
TARGETBINDIR = .
|
||||||
|
TESTBINDIR = tests
|
||||||
|
TARGETLIBDIR = .
|
||||||
|
# Name of the targets
|
||||||
|
LIBOPUSFILE_TARGET = libopusfile.a
|
||||||
|
LIBOPUSURL_TARGET = libopusurl.a
|
||||||
|
OPUSFILE_EXAMPLE_TARGET = opusfile_example
|
||||||
|
SEEKING_EXAMPLE_TARGET = seeking_example
|
||||||
|
# Test targets
|
||||||
|
#TODO: tests
|
||||||
|
FOO_TARGET = foo
|
||||||
|
# The command to use to generate dependency information
|
||||||
|
MAKEDEPEND = ${CC} -MM
|
||||||
|
#MAKEDEPEND = makedepend -f- -Y --
|
||||||
|
# Optional features to enable
|
||||||
|
#CFLAGS := $(CFLAGS) -DOP_HAVE_LRINTF
|
||||||
|
CFLAGS := $(CFLAGS) -DOP_ENABLE_HTTP
|
||||||
|
# Extra compilation flags.
|
||||||
|
# You may get speed increases by including flags such as -O2 or -O3 or
|
||||||
|
# -ffast-math, or additional flags, depending on your system and compiler.
|
||||||
|
# The -g flag will generally include debugging information.
|
||||||
|
CFLAGS := -g $(CFLAGS)
|
||||||
|
CFLAGS := -DOP_ENABLE_ASSERTIONS $(CFLAGS)
|
||||||
|
# These are gcc-only, but not actually critical.
|
||||||
|
CFLAGS := -fPIC $(CFLAGS)
|
||||||
|
CFLAGS := -std=c89 -pedantic $(CFLAGS)
|
||||||
|
CFLAGS := -fvisibility=hidden $(CFLAGS)
|
||||||
|
CFLAGS := -Wextra -Wno-parentheses -Wno-long-long $(CFLAGS)
|
||||||
|
CFLAGS := -Wall $(CFLAGS)
|
||||||
|
# The list of pkg-config packages we depend on.
|
||||||
|
PACKAGES := ogg opus
|
||||||
|
ifeq ($(findstring -DOP_ENABLE_HTTP,${CFLAGS}),-DOP_ENABLE_HTTP) |
||||||
|
PACKAGES += openssl
|
||||||
|
endif |
||||||
|
# The location of include files.
|
||||||
|
# Modify these to point to your Ogg and Opus include directories if they are
|
||||||
|
# not installed in a standard location.
|
||||||
|
CINCLUDE := `pkg-config --cflags ${PACKAGES}`
|
||||||
|
|
||||||
|
# Libraries to link with, and the location of library files.
|
||||||
|
LIBS := `pkg-config --libs ${PACKAGES}`
|
||||||
|
ifeq ($(findstring -DOP_HAVE_LRINTF,${CFLAGS}),-DOP_HAVE_LRINTF) |
||||||
|
LIBS := -lm $(LIBS)
|
||||||
|
endif |
||||||
|
|
||||||
|
# Extras for the MS target
|
||||||
|
ifneq ($(findstring mingw,${CC}),) |
||||||
|
LIBS += -lwsock32 -lws2_32 -lgdi32 -lcrypt32
|
||||||
|
EXEEXT := .exe
|
||||||
|
endif |
||||||
|
|
||||||
|
RANLIB ?= ranlib
|
||||||
|
|
||||||
|
#TODO: tests
|
||||||
|
FOO_LIBS =
|
||||||
|
|
||||||
|
# ANYTHING BELOW THIS LINE PROBABLY DOES NOT NEED EDITING
|
||||||
|
CINCLUDE := -I../include ${CINCLUDE}
|
||||||
|
LIBSRCDIR = ../src
|
||||||
|
BINSRCDIR = ../examples
|
||||||
|
TESTSRCDIR = ${LIBSRCDIR}
|
||||||
|
WORKDIR = objs
|
||||||
|
|
||||||
|
# C source file lists
|
||||||
|
LIBOPUSFILE_CSOURCES = \
|
||||||
|
http.c \ |
||||||
|
info.c \ |
||||||
|
internal.c \ |
||||||
|
opusfile.c \ |
||||||
|
stream.c \ |
||||||
|
|
||||||
|
LIBOPUSFILE_CHEADERS = \
|
||||||
|
internal.h \ |
||||||
|
|
||||||
|
LIBOPUSURL_CSOURCES = \
|
||||||
|
internal.c \ |
||||||
|
http.c \ |
||||||
|
|
||||||
|
ifneq ($(findstring mingw,${CC}),) |
||||||
|
LIBOPUSURL_CSOURCES += wincerts.c
|
||||||
|
endif |
||||||
|
|
||||||
|
LIBOPUSURL_CHEADERS = \
|
||||||
|
internal.h \ |
||||||
|
|
||||||
|
OPUSFILE_EXAMPLE_CSOURCES = opusfile_example.c
|
||||||
|
|
||||||
|
SEEKING_EXAMPLE_CSOURCES = seeking_example.c
|
||||||
|
|
||||||
|
ifneq ($(findstring mingw,${CC}),) |
||||||
|
OPUSFILE_EXAMPLE_CSOURCES += win32utf8.c
|
||||||
|
SEEKING_EXAMPLE_CSOURCES += win32utf8.c
|
||||||
|
endif |
||||||
|
|
||||||
|
FOO_CSOURCES = tests/foo.c
|
||||||
|
|
||||||
|
# Create object file list.
|
||||||
|
LIBOPUSFILE_OBJS:= ${LIBOPUSFILE_CSOURCES:%.c=${WORKDIR}/%.o}
|
||||||
|
LIBOPUSFILE_ASMS:= ${LIBOPUSFILE_OBJS:%.o=%.s}
|
||||||
|
LIBOPUSFILE_DEPS:= ${LIBOPUSFILE_OBJS:%.o=%.d}
|
||||||
|
LIBOPUSURL_OBJS:= ${LIBOPUSURL_CSOURCES:%.c=${WORKDIR}/%.o}
|
||||||
|
LIBOPUSURL_ASMS:= ${LIBOPUSURL_OBJS:%.o=%.s}
|
||||||
|
LIBOPUSURL_DEPS:= ${LIBOPUSURL_OBJS:%.o=%.d}
|
||||||
|
OPUSFILE_EXAMPLE_OBJS:= ${OPUSFILE_EXAMPLE_CSOURCES:%.c=${WORKDIR}/%.o}
|
||||||
|
SEEKING_EXAMPLE_OBJS:= ${SEEKING_EXAMPLE_CSOURCES:%.c=${WORKDIR}/%.o}
|
||||||
|
#TODO: tests
|
||||||
|
FOO_OBJS:= ${FOO_CSOURCES:%.c=${WORKDIR}/%.o}
|
||||||
|
ALL_OBJS:= \
|
||||||
|
${LIBOPUSFILE_OBJS} \
|
||||||
|
${LIBOPUSURL_OBJS} \
|
||||||
|
${OPUSFILE_EXAMPLE_OBJS} \
|
||||||
|
${SEEKING_EXAMPLE_OBJS} \
|
||||||
|
|
||||||
|
#TODO: tests
|
||||||
|
# ${FOO_OBJS}
|
||||||
|
|
||||||
|
# Create the dependency file list
|
||||||
|
ALL_DEPS:= ${ALL_OBJS:%.o=%.d}
|
||||||
|
# Prepend source path to file names.
|
||||||
|
LIBOPUSFILE_CSOURCES:= ${LIBOPUSFILE_CSOURCES:%=${LIBSRCDIR}/%}
|
||||||
|
LIBOPUSFILE_CHEADERS:= ${LIBOPUSFILE_CHEADERS:%=${LIBSRCDIR}/%}
|
||||||
|
LIBOPUSURL_CSOURCES:= ${LIBOPUSURL_CSOURCES:%=${LIBSRCDIR}/%}
|
||||||
|
LIBOPUSURL_CHEADERS:= ${LIBOPUSURL_CHEADERS:%=${LIBSRCDIR}/%}
|
||||||
|
OPUSFILE_EXAMPLE_CSOURCES:= ${OPUSFILE_EXAMPLE_CSOURCES:%=${BINSRCDIR}/%}
|
||||||
|
SEEKING_EXAMPLE_CSOURCES:= ${SEEKING_EXAMPLE_CSOURCES:%=${BINSRCDIR}/%}
|
||||||
|
#TODO: tests
|
||||||
|
FOO_CSOURCES:= ${FOO_CSOURCES:%=${TESTSRCDIR}/%}
|
||||||
|
ALL_CSOURCES:= \
|
||||||
|
${LIBOPUSFILE_CSOURCES} \
|
||||||
|
${LIBOPUSURL_CSOURCES} \
|
||||||
|
${OPUSFILE_EXAMPLE_CSOURCES} \
|
||||||
|
${SEEKING_EXAMPLE_CSOURCES} \
|
||||||
|
|
||||||
|
#TODO: tests
|
||||||
|
# ${FOO_CSOURCES} \
|
||||||
|
# Prepand target path to file names.
|
||||||
|
LIBOPUSFILE_TARGET:= ${TARGETLIBDIR}/${LIBOPUSFILE_TARGET}
|
||||||
|
LIBOPUSURL_TARGET:= ${TARGETLIBDIR}/${LIBOPUSURL_TARGET}
|
||||||
|
OPUSFILE_EXAMPLE_TARGET:= ${TARGETBINDIR}/${OPUSFILE_EXAMPLE_TARGET}${EXEEXT}
|
||||||
|
SEEKING_EXAMPLE_TARGET:= ${TARGETBINDIR}/${SEEKING_EXAMPLE_TARGET}${EXEEXT}
|
||||||
|
# Prepend test path to file names.
|
||||||
|
#TODO: tests
|
||||||
|
FOO_TARGET:= ${TESTBINDIR}/${FOO_TARGET}
|
||||||
|
# Complete set of targets
|
||||||
|
ALL_TARGETS:= \
|
||||||
|
${LIBOPUSFILE_TARGET} \
|
||||||
|
${LIBOPUSURL_TARGET} \
|
||||||
|
${OPUSFILE_EXAMPLE_TARGET} \
|
||||||
|
${SEEKING_EXAMPLE_TARGET} \
|
||||||
|
|
||||||
|
#TODO: tests
|
||||||
|
# ${FOO_TARGET} \
|
||||||
|
|
||||||
|
# Targets:
|
||||||
|
# Everything (default)
|
||||||
|
all: ${ALL_TARGETS} |
||||||
|
|
||||||
|
# libopusfile
|
||||||
|
${LIBOPUSFILE_TARGET}: ${LIBOPUSFILE_OBJS} |
||||||
|
mkdir -p ${TARGETLIBDIR}
|
||||||
|
$(AR) cqs $@ ${LIBOPUSFILE_OBJS}
|
||||||
|
-$(RANLIB) $@
|
||||||
|
|
||||||
|
# libopusurl
|
||||||
|
${LIBOPUSURL_TARGET}: ${LIBOPUSURL_OBJS} |
||||||
|
mkdir -p ${TARGETLIBDIR}
|
||||||
|
$(AR) cqs $@ ${LIBOPUSURL_OBJS}
|
||||||
|
-$(RANLIB) $@
|
||||||
|
|
||||||
|
# opusfile_example
|
||||||
|
${OPUSFILE_EXAMPLE_TARGET}: ${OPUSFILE_EXAMPLE_OBJS} ${LIBOPUSFILE_TARGET} \
|
||||||
|
${LIBOPUSURL_TARGET}
|
||||||
|
mkdir -p ${TARGETBINDIR}
|
||||||
|
${CC} ${CFLAGS} ${OPUSFILE_EXAMPLE_OBJS} ${LIBOPUSFILE_TARGET} \
|
||||||
|
${LIBOPUSURL_TARGET} ${LIBS} -o $@
|
||||||
|
|
||||||
|
# seeking_example
|
||||||
|
${SEEKING_EXAMPLE_TARGET}: ${SEEKING_EXAMPLE_OBJS} ${LIBOPUSFILE_TARGET} \
|
||||||
|
${LIBOPUSURL_TARGET}
|
||||||
|
mkdir -p ${TARGETBINDIR}
|
||||||
|
${CC} ${CFLAGS} ${SEEKING_EXAMPLE_OBJS} ${LIBOPUSFILE_TARGET} \
|
||||||
|
${LIBOPUSURL_TARGET} ${LIBS} -o $@
|
||||||
|
|
||||||
|
#TODO:
|
||||||
|
#tests: foo
|
||||||
|
#
|
||||||
|
#${FOO_TARGET}: ${FOO_OBJS}
|
||||||
|
# mkdir -p ${TESTBINDIR}
|
||||||
|
# ${CC} ${CFLAGS} ${FOO_OBJS} ${FOO_LIBS} -o $@
|
||||||
|
#
|
||||||
|
#tests-clean:
|
||||||
|
# -rmdir ${TESTBINDIR}
|
||||||
|
|
||||||
|
# Assembly listing
|
||||||
|
ALL_ASM := ${ALL_OBJS:%.o=%.s}
|
||||||
|
asm: ${ALL_ASM} |
||||||
|
|
||||||
|
# Check that build is complete.
|
||||||
|
check: all |
||||||
|
|
||||||
|
# Remove all targets.
|
||||||
|
clean: |
||||||
|
${RM} ${ALL_ASM} ${ALL_OBJS} ${ALL_DEPS}
|
||||||
|
${RM} ${ALL_TARGETS}
|
||||||
|
-rmdir ${WORKDIR}
|
||||||
|
|
||||||
|
# Make everything depend on changes in the Makefile
|
||||||
|
# This vpath directive needs to be before any include statements
|
||||||
|
vpath Makefile $(dir $(lastword $(MAKEFILE_LIST))) |
||||||
|
${ALL_ASM} ${ALL_OBJS} ${ALL_DEPS} ${ALL_TARGETS} : Makefile |
||||||
|
|
||||||
|
# Specify which targets are phony for GNU make
|
||||||
|
.PHONY : all clean check |
||||||
|
|
||||||
|
# Rules
|
||||||
|
${WORKDIR}/%.d: ${LIBSRCDIR}/%.c |
||||||
|
mkdir -p ${dir $@}
|
||||||
|
${MAKEDEPEND} ${CINCLUDE} ${CFLAGS} $< -MT ${@:%.d=%.o} > $@
|
||||||
|
${MAKEDEPEND} ${CINCLUDE} ${CFLAGS} $< -MT ${@:%.d=%.s} >> $@
|
||||||
|
${MAKEDEPEND} ${CINCLUDE} ${CFLAGS} $< -MT $@ >> $@
|
||||||
|
${WORKDIR}/%.s: ${LIBSRCDIR}/%.c |
||||||
|
mkdir -p ${dir $@}
|
||||||
|
${CC} ${CINCLUDE} ${CFLAGS} -S -o $@ $<
|
||||||
|
${WORKDIR}/%.o: ${LIBSRCDIR}/%.c |
||||||
|
mkdir -p ${dir $@}
|
||||||
|
${CC} ${CINCLUDE} ${CFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
|
${WORKDIR}/%.d : ${BINSRCDIR}/%.c |
||||||
|
mkdir -p ${dir $@}
|
||||||
|
${MAKEDEPEND} ${CINCLUDE} ${CFLAGS} $< -MT ${@:%.d=%.o} > $@
|
||||||
|
${WORKDIR}/%.s : ${BINSRCDIR}/%.c ${WORKDIR}/%.o |
||||||
|
mkdir -p ${dir $@}
|
||||||
|
${CC} ${CINCLUDE} ${CFLAGS} -S -o $@ $<
|
||||||
|
${WORKDIR}/%.o : ${BINSRCDIR}/%.c |
||||||
|
mkdir -p ${dir $@}
|
||||||
|
${CC} ${CINCLUDE} ${CFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
|
# Include header file dependencies, except when cleaning
|
||||||
|
ifneq ($(MAKECMDGOALS),clean) |
||||||
|
include ${ALL_DEPS} |
||||||
|
endif |
@ -1,43 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright 2023 jacqueline <me@jacqueline.id.au> |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: GPL-3.0-only |
|
||||||
*/ |
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <sys/_stdint.h> |
|
||||||
#include <cstddef> |
|
||||||
#include <cstdint> |
|
||||||
#include <optional> |
|
||||||
|
|
||||||
#include "ogg/ogg.h" |
|
||||||
#include "span.hpp" |
|
||||||
|
|
||||||
namespace codecs { |
|
||||||
|
|
||||||
class OggContainer { |
|
||||||
public: |
|
||||||
OggContainer(); |
|
||||||
~OggContainer(); |
|
||||||
|
|
||||||
auto AddBytes(cpp::span<const std::byte>) -> bool; |
|
||||||
|
|
||||||
auto Next() -> bool; |
|
||||||
auto Current() -> cpp::span<uint8_t>; |
|
||||||
auto HasPacket() -> bool; |
|
||||||
|
|
||||||
private: |
|
||||||
auto AdvancePage() -> bool; |
|
||||||
auto AdvancePacket() -> bool; |
|
||||||
|
|
||||||
ogg_sync_state sync_; |
|
||||||
ogg_stream_state stream_; |
|
||||||
ogg_page page_; |
|
||||||
ogg_packet packet_; |
|
||||||
|
|
||||||
bool has_stream_; |
|
||||||
bool has_packet_; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace codecs
|
|
@ -1,109 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright 2023 jacqueline <me@jacqueline.id.au> |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: GPL-3.0-only |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "ogg.hpp" |
|
||||||
#include <cstring> |
|
||||||
|
|
||||||
#include "esp_log.h" |
|
||||||
#include "ogg/ogg.h" |
|
||||||
|
|
||||||
namespace codecs { |
|
||||||
|
|
||||||
static constexpr char kTag[] = "ogg"; |
|
||||||
|
|
||||||
OggContainer::OggContainer() |
|
||||||
: sync_(), |
|
||||||
stream_(), |
|
||||||
page_(), |
|
||||||
packet_(), |
|
||||||
has_stream_(false), |
|
||||||
has_packet_(false) { |
|
||||||
ogg_sync_init(&sync_); |
|
||||||
ogg_sync_pageout(&sync_, &page_); |
|
||||||
} |
|
||||||
|
|
||||||
OggContainer::~OggContainer() { |
|
||||||
ogg_sync_clear(&sync_); |
|
||||||
if (has_stream_) { |
|
||||||
ogg_stream_clear(&stream_); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
auto OggContainer::AddBytes(cpp::span<const std::byte> in) -> bool { |
|
||||||
ESP_LOGI(kTag, "adding %u bytes to buffer", in.size()); |
|
||||||
char* buf = ogg_sync_buffer(&sync_, in.size()); |
|
||||||
if (buf == NULL) { |
|
||||||
ESP_LOGE(kTag, "failed to allocate sync buffer"); |
|
||||||
return false; |
|
||||||
} |
|
||||||
std::memcpy(buf, in.data(), in.size()); |
|
||||||
if (ogg_sync_wrote(&sync_, in.size()) < 0) { |
|
||||||
ESP_LOGE(kTag, "failed to write to sync buffer"); |
|
||||||
return false; |
|
||||||
} |
|
||||||
return AdvancePage() && AdvancePacket(); |
|
||||||
} |
|
||||||
|
|
||||||
auto OggContainer::HasPacket() -> bool { |
|
||||||
return has_packet_; |
|
||||||
} |
|
||||||
|
|
||||||
auto OggContainer::Next() -> bool { |
|
||||||
if (AdvancePacket()) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
if (AdvancePage() && AdvancePacket()) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
auto OggContainer::Current() -> cpp::span<uint8_t> { |
|
||||||
if (!has_packet_) { |
|
||||||
return {}; |
|
||||||
} |
|
||||||
ESP_LOGI(kTag, "getting packet, location %p size %li", packet_.packet, |
|
||||||
packet_.bytes); |
|
||||||
return {packet_.packet, static_cast<size_t>(packet_.bytes)}; |
|
||||||
} |
|
||||||
|
|
||||||
auto OggContainer::AdvancePage() -> bool { |
|
||||||
int err; |
|
||||||
if ((err = ogg_sync_pageout(&sync_, &page_)) != 1) { |
|
||||||
ESP_LOGE(kTag, "failed to assemble page, res %i", err); |
|
||||||
return false; |
|
||||||
} |
|
||||||
if (!has_stream_) { |
|
||||||
int serialno = ogg_page_serialno(&page_); |
|
||||||
ESP_LOGI(kTag, "beginning ogg stream, serial number %i", serialno); |
|
||||||
if ((err = ogg_stream_init(&stream_, serialno) < 0)) { |
|
||||||
ESP_LOGE(kTag, "failed to init stream page, res %i", err); |
|
||||||
return false; |
|
||||||
} |
|
||||||
has_stream_ = true; |
|
||||||
} |
|
||||||
if (ogg_stream_pagein(&stream_, &page_) < 0) { |
|
||||||
ESP_LOGE(kTag, "failed to read in page"); |
|
||||||
return false; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
auto OggContainer::AdvancePacket() -> bool { |
|
||||||
has_packet_ = false; |
|
||||||
int res; |
|
||||||
while ((res = ogg_stream_packetout(&stream_, &packet_)) == -1) { |
|
||||||
// Retry until we sync, or run out of data.
|
|
||||||
ESP_LOGW(kTag, "trying to sync stream..."); |
|
||||||
} |
|
||||||
has_packet_ = res; |
|
||||||
if (!has_packet_) { |
|
||||||
ESP_LOGE(kTag, "failed to read out packet"); |
|
||||||
} |
|
||||||
return has_packet_; |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace codecs
|
|
Loading…
Reference in new issue