Built SDL2_image and _mixer static

This commit is contained in:
2022-09-30 15:49:16 -04:00
parent e2605bf6c1
commit 1dec4347e0
4473 changed files with 1964551 additions and 9 deletions

View File

@ -0,0 +1,100 @@
# FLAC - Free Lossless Audio Codec
# Copyright (C) 2002-2009 Josh Coalson
# Copyright (C) 2011-2016 Xiph.Org Foundation
#
# This file is part the FLAC project. FLAC is comprised of several
# components distributed under different licenses. The codec libraries
# are distributed under Xiph.Org's BSD-like license (see the file
# COPYING.Xiph in this distribution). All other programs, libraries, and
# plugins are distributed under the GPL (see COPYING.GPL). The documentation
# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the
# FLAC distribution contains at the top the terms under which it may be
# distributed.
#
# Since this particular file is relevant to all components of FLAC,
# it may be distributed under the Xiph.Org license, which is the least
# restrictive of those mentioned above. See the file COPYING.Xiph in this
# distribution.
AUTOMAKE_OPTIONS = subdir-objects
AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include
EXTRA_DIST = \
Makefile.lite \
README \
getopt/Makefile.lite \
getopt/getopt_static.vcproj \
getopt/getopt_static.vcxproj \
getopt/getopt_static.vcxproj.filters \
grabbag/Makefile.lite \
grabbag/grabbag_static.vcproj \
grabbag/grabbag_static.vcxproj \
grabbag/grabbag_static.vcxproj.filters \
replaygain_analysis/Makefile.lite \
replaygain_analysis/replaygain_analysis_static.vcproj \
replaygain_analysis/replaygain_analysis_static.vcxproj \
replaygain_analysis/replaygain_analysis_static.vcxproj.filters \
replaygain_synthesis/Makefile.lite \
replaygain_synthesis/replaygain_synthesis_static.vcproj \
replaygain_synthesis/replaygain_synthesis_static.vcxproj \
replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters \
utf8/Makefile.lite \
utf8/charmaps.h \
utf8/makemap.c \
utf8/charset_test.c \
utf8/utf8_static.vcproj \
utf8/utf8_static.vcxproj \
utf8/utf8_static.vcxproj.filters \
win_utf8_io/Makefile.lite \
win_utf8_io/win_utf8_io_static.vcproj \
win_utf8_io/win_utf8_io_static.vcxproj \
win_utf8_io/win_utf8_io_static.vcxproj.filters
noinst_LTLIBRARIES = \
getopt/libgetopt.la \
grabbag/libgrabbag.la \
utf8/libutf8.la \
$(libwin_utf8_io) \
replaygain_analysis/libreplaygain_analysis.la \
replaygain_synthesis/libreplaygain_synthesis.la
if OS_IS_WINDOWS
win_utf8_io_libwin_utf8_io_la_SOURCES = win_utf8_io/win_utf8_io.c
libwin_utf8_io = win_utf8_io/libwin_utf8_io.la
win_utf8_io_libwin_utf8_io_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -lm
else
win_utf8_io_libwin_utf8_io_la_SOURCES =
libwin_utf8_io =
endif
getopt_libgetopt_la_SOURCES = getopt/getopt.c getopt/getopt1.c
grabbag_libgrabbag_la_SOURCES = \
grabbag/alloc.c \
grabbag/cuesheet.c \
grabbag/file.c \
grabbag/picture.c \
grabbag/replaygain.c \
grabbag/seektable.c \
grabbag/snprintf.c
utf8_libutf8_la_SOURCES = \
utf8/charset.c \
utf8/charset.h \
utf8/iconvert.c \
utf8/iconvert.h \
utf8/utf8.c
replaygain_analysis_libreplaygain_analysis_la_SOURCES = replaygain_analysis/replaygain_analysis.c
replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS = -I $(top_srcdir)/src/share/replaygain_synthesis/include
replaygain_synthesis_libreplaygain_synthesis_la_SOURCES = replaygain_synthesis/replaygain_synthesis.c
debug:
$(MAKE) all CFLAGS="@DEBUG@"
profile:
$(MAKE) all CFLAGS="@PROFILE@"

View File

@ -0,0 +1,892 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# FLAC - Free Lossless Audio Codec
# Copyright (C) 2002-2009 Josh Coalson
# Copyright (C) 2011-2016 Xiph.Org Foundation
#
# This file is part the FLAC project. FLAC is comprised of several
# components distributed under different licenses. The codec libraries
# are distributed under Xiph.Org's BSD-like license (see the file
# COPYING.Xiph in this distribution). All other programs, libraries, and
# plugins are distributed under the GPL (see COPYING.GPL). The documentation
# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the
# FLAC distribution contains at the top the terms under which it may be
# distributed.
#
# Since this particular file is relevant to all components of FLAC,
# it may be distributed under the Xiph.Org license, which is the least
# restrictive of those mentioned above. See the file COPYING.Xiph in this
# distribution.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/share
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/add_cflags.m4 \
$(top_srcdir)/m4/add_cxxflags.m4 $(top_srcdir)/m4/bswap.m4 \
$(top_srcdir)/m4/clang.m4 $(top_srcdir)/m4/codeset.m4 \
$(top_srcdir)/m4/gcc_version.m4 $(top_srcdir)/m4/iconv.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/ogg.m4 $(top_srcdir)/m4/really_gcc.m4 \
$(top_srcdir)/m4/stack_protect.m4 $(top_srcdir)/m4/xmms.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
getopt_libgetopt_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
am_getopt_libgetopt_la_OBJECTS = getopt/getopt.lo getopt/getopt1.lo
getopt_libgetopt_la_OBJECTS = $(am_getopt_libgetopt_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
grabbag_libgrabbag_la_LIBADD =
am_grabbag_libgrabbag_la_OBJECTS = grabbag/alloc.lo \
grabbag/cuesheet.lo grabbag/file.lo grabbag/picture.lo \
grabbag/replaygain.lo grabbag/seektable.lo grabbag/snprintf.lo
grabbag_libgrabbag_la_OBJECTS = $(am_grabbag_libgrabbag_la_OBJECTS)
replaygain_analysis_libreplaygain_analysis_la_LIBADD =
am_replaygain_analysis_libreplaygain_analysis_la_OBJECTS = \
replaygain_analysis/replaygain_analysis.lo
replaygain_analysis_libreplaygain_analysis_la_OBJECTS = \
$(am_replaygain_analysis_libreplaygain_analysis_la_OBJECTS)
replaygain_synthesis_libreplaygain_synthesis_la_LIBADD =
am_replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS = replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo
replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS = \
$(am_replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS)
replaygain_synthesis_libreplaygain_synthesis_la_LINK = $(LIBTOOL) \
$(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) \
$(replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
utf8_libutf8_la_LIBADD =
am_utf8_libutf8_la_OBJECTS = utf8/charset.lo utf8/iconvert.lo \
utf8/utf8.lo
utf8_libutf8_la_OBJECTS = $(am_utf8_libutf8_la_OBJECTS)
@OS_IS_WINDOWS_TRUE@win_utf8_io_libwin_utf8_io_la_DEPENDENCIES = \
@OS_IS_WINDOWS_TRUE@ $(top_builddir)/src/libFLAC/libFLAC.la
am__win_utf8_io_libwin_utf8_io_la_SOURCES_DIST = \
win_utf8_io/win_utf8_io.c
@OS_IS_WINDOWS_TRUE@am_win_utf8_io_libwin_utf8_io_la_OBJECTS = \
@OS_IS_WINDOWS_TRUE@ win_utf8_io/win_utf8_io.lo
win_utf8_io_libwin_utf8_io_la_OBJECTS = \
$(am_win_utf8_io_libwin_utf8_io_la_OBJECTS)
@OS_IS_WINDOWS_TRUE@am_win_utf8_io_libwin_utf8_io_la_rpath =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(getopt_libgetopt_la_SOURCES) \
$(grabbag_libgrabbag_la_SOURCES) \
$(replaygain_analysis_libreplaygain_analysis_la_SOURCES) \
$(replaygain_synthesis_libreplaygain_synthesis_la_SOURCES) \
$(utf8_libutf8_la_SOURCES) \
$(win_utf8_io_libwin_utf8_io_la_SOURCES)
DIST_SOURCES = $(getopt_libgetopt_la_SOURCES) \
$(grabbag_libgrabbag_la_SOURCES) \
$(replaygain_analysis_libreplaygain_analysis_la_SOURCES) \
$(replaygain_synthesis_libreplaygain_synthesis_la_SOURCES) \
$(utf8_libutf8_la_SOURCES) \
$(am__win_utf8_io_libwin_utf8_io_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@
DOXYGEN = @DOXYGEN@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_64_BIT_WORDS = @ENABLE_64_BIT_WORDS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FLAC__HAS_OGG = @FLAC__HAS_OGG@
FLAC__TEST_LEVEL = @FLAC__TEST_LEVEL@
FLAC__TEST_WITH_VALGRIND = @FLAC__TEST_WITH_VALGRIND@
GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@
GCC_MINOR_VERSION = @GCC_MINOR_VERSION@
GCC_VERSION = @GCC_VERSION@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NASM = @NASM@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OBJ_FORMAT = @OBJ_FORMAT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
OGG_PACKAGE = @OGG_PACKAGE@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
XMMS_CFLAGS = @XMMS_CFLAGS@
XMMS_CONFIG = @XMMS_CONFIG@
XMMS_DATA_DIR = @XMMS_DATA_DIR@
XMMS_EFFECT_PLUGIN_DIR = @XMMS_EFFECT_PLUGIN_DIR@
XMMS_GENERAL_PLUGIN_DIR = @XMMS_GENERAL_PLUGIN_DIR@
XMMS_INPUT_PLUGIN_DIR = @XMMS_INPUT_PLUGIN_DIR@
XMMS_LIBS = @XMMS_LIBS@
XMMS_OUTPUT_PLUGIN_DIR = @XMMS_OUTPUT_PLUGIN_DIR@
XMMS_PLUGIN_DIR = @XMMS_PLUGIN_DIR@
XMMS_VERSION = @XMMS_VERSION@
XMMS_VISUALIZATION_PLUGIN_DIR = @XMMS_VISUALIZATION_PLUGIN_DIR@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = subdir-objects
AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include
EXTRA_DIST = \
Makefile.lite \
README \
getopt/Makefile.lite \
getopt/getopt_static.vcproj \
getopt/getopt_static.vcxproj \
getopt/getopt_static.vcxproj.filters \
grabbag/Makefile.lite \
grabbag/grabbag_static.vcproj \
grabbag/grabbag_static.vcxproj \
grabbag/grabbag_static.vcxproj.filters \
replaygain_analysis/Makefile.lite \
replaygain_analysis/replaygain_analysis_static.vcproj \
replaygain_analysis/replaygain_analysis_static.vcxproj \
replaygain_analysis/replaygain_analysis_static.vcxproj.filters \
replaygain_synthesis/Makefile.lite \
replaygain_synthesis/replaygain_synthesis_static.vcproj \
replaygain_synthesis/replaygain_synthesis_static.vcxproj \
replaygain_synthesis/replaygain_synthesis_static.vcxproj.filters \
utf8/Makefile.lite \
utf8/charmaps.h \
utf8/makemap.c \
utf8/charset_test.c \
utf8/utf8_static.vcproj \
utf8/utf8_static.vcxproj \
utf8/utf8_static.vcxproj.filters \
win_utf8_io/Makefile.lite \
win_utf8_io/win_utf8_io_static.vcproj \
win_utf8_io/win_utf8_io_static.vcxproj \
win_utf8_io/win_utf8_io_static.vcxproj.filters
noinst_LTLIBRARIES = \
getopt/libgetopt.la \
grabbag/libgrabbag.la \
utf8/libutf8.la \
$(libwin_utf8_io) \
replaygain_analysis/libreplaygain_analysis.la \
replaygain_synthesis/libreplaygain_synthesis.la
@OS_IS_WINDOWS_FALSE@win_utf8_io_libwin_utf8_io_la_SOURCES =
@OS_IS_WINDOWS_TRUE@win_utf8_io_libwin_utf8_io_la_SOURCES = win_utf8_io/win_utf8_io.c
@OS_IS_WINDOWS_FALSE@libwin_utf8_io =
@OS_IS_WINDOWS_TRUE@libwin_utf8_io = win_utf8_io/libwin_utf8_io.la
@OS_IS_WINDOWS_TRUE@win_utf8_io_libwin_utf8_io_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -lm
getopt_libgetopt_la_SOURCES = getopt/getopt.c getopt/getopt1.c
grabbag_libgrabbag_la_SOURCES = \
grabbag/alloc.c \
grabbag/cuesheet.c \
grabbag/file.c \
grabbag/picture.c \
grabbag/replaygain.c \
grabbag/seektable.c \
grabbag/snprintf.c
utf8_libutf8_la_SOURCES = \
utf8/charset.c \
utf8/charset.h \
utf8/iconvert.c \
utf8/iconvert.h \
utf8/utf8.c
replaygain_analysis_libreplaygain_analysis_la_SOURCES = replaygain_analysis/replaygain_analysis.c
replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS = -I $(top_srcdir)/src/share/replaygain_synthesis/include
replaygain_synthesis_libreplaygain_synthesis_la_SOURCES = replaygain_synthesis/replaygain_synthesis.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/share/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/share/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
getopt/$(am__dirstamp):
@$(MKDIR_P) getopt
@: > getopt/$(am__dirstamp)
getopt/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) getopt/$(DEPDIR)
@: > getopt/$(DEPDIR)/$(am__dirstamp)
getopt/getopt.lo: getopt/$(am__dirstamp) \
getopt/$(DEPDIR)/$(am__dirstamp)
getopt/getopt1.lo: getopt/$(am__dirstamp) \
getopt/$(DEPDIR)/$(am__dirstamp)
getopt/libgetopt.la: $(getopt_libgetopt_la_OBJECTS) $(getopt_libgetopt_la_DEPENDENCIES) $(EXTRA_getopt_libgetopt_la_DEPENDENCIES) getopt/$(am__dirstamp)
$(AM_V_CCLD)$(LINK) $(getopt_libgetopt_la_OBJECTS) $(getopt_libgetopt_la_LIBADD) $(LIBS)
grabbag/$(am__dirstamp):
@$(MKDIR_P) grabbag
@: > grabbag/$(am__dirstamp)
grabbag/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) grabbag/$(DEPDIR)
@: > grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/alloc.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/cuesheet.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/file.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/picture.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/replaygain.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/seektable.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/snprintf.lo: grabbag/$(am__dirstamp) \
grabbag/$(DEPDIR)/$(am__dirstamp)
grabbag/libgrabbag.la: $(grabbag_libgrabbag_la_OBJECTS) $(grabbag_libgrabbag_la_DEPENDENCIES) $(EXTRA_grabbag_libgrabbag_la_DEPENDENCIES) grabbag/$(am__dirstamp)
$(AM_V_CCLD)$(LINK) $(grabbag_libgrabbag_la_OBJECTS) $(grabbag_libgrabbag_la_LIBADD) $(LIBS)
replaygain_analysis/$(am__dirstamp):
@$(MKDIR_P) replaygain_analysis
@: > replaygain_analysis/$(am__dirstamp)
replaygain_analysis/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) replaygain_analysis/$(DEPDIR)
@: > replaygain_analysis/$(DEPDIR)/$(am__dirstamp)
replaygain_analysis/replaygain_analysis.lo: \
replaygain_analysis/$(am__dirstamp) \
replaygain_analysis/$(DEPDIR)/$(am__dirstamp)
replaygain_analysis/libreplaygain_analysis.la: $(replaygain_analysis_libreplaygain_analysis_la_OBJECTS) $(replaygain_analysis_libreplaygain_analysis_la_DEPENDENCIES) $(EXTRA_replaygain_analysis_libreplaygain_analysis_la_DEPENDENCIES) replaygain_analysis/$(am__dirstamp)
$(AM_V_CCLD)$(LINK) $(replaygain_analysis_libreplaygain_analysis_la_OBJECTS) $(replaygain_analysis_libreplaygain_analysis_la_LIBADD) $(LIBS)
replaygain_synthesis/$(am__dirstamp):
@$(MKDIR_P) replaygain_synthesis
@: > replaygain_synthesis/$(am__dirstamp)
replaygain_synthesis/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) replaygain_synthesis/$(DEPDIR)
@: > replaygain_synthesis/$(DEPDIR)/$(am__dirstamp)
replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo: \
replaygain_synthesis/$(am__dirstamp) \
replaygain_synthesis/$(DEPDIR)/$(am__dirstamp)
replaygain_synthesis/libreplaygain_synthesis.la: $(replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS) $(replaygain_synthesis_libreplaygain_synthesis_la_DEPENDENCIES) $(EXTRA_replaygain_synthesis_libreplaygain_synthesis_la_DEPENDENCIES) replaygain_synthesis/$(am__dirstamp)
$(AM_V_CCLD)$(replaygain_synthesis_libreplaygain_synthesis_la_LINK) $(replaygain_synthesis_libreplaygain_synthesis_la_OBJECTS) $(replaygain_synthesis_libreplaygain_synthesis_la_LIBADD) $(LIBS)
utf8/$(am__dirstamp):
@$(MKDIR_P) utf8
@: > utf8/$(am__dirstamp)
utf8/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) utf8/$(DEPDIR)
@: > utf8/$(DEPDIR)/$(am__dirstamp)
utf8/charset.lo: utf8/$(am__dirstamp) utf8/$(DEPDIR)/$(am__dirstamp)
utf8/iconvert.lo: utf8/$(am__dirstamp) utf8/$(DEPDIR)/$(am__dirstamp)
utf8/utf8.lo: utf8/$(am__dirstamp) utf8/$(DEPDIR)/$(am__dirstamp)
utf8/libutf8.la: $(utf8_libutf8_la_OBJECTS) $(utf8_libutf8_la_DEPENDENCIES) $(EXTRA_utf8_libutf8_la_DEPENDENCIES) utf8/$(am__dirstamp)
$(AM_V_CCLD)$(LINK) $(utf8_libutf8_la_OBJECTS) $(utf8_libutf8_la_LIBADD) $(LIBS)
win_utf8_io/$(am__dirstamp):
@$(MKDIR_P) win_utf8_io
@: > win_utf8_io/$(am__dirstamp)
win_utf8_io/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) win_utf8_io/$(DEPDIR)
@: > win_utf8_io/$(DEPDIR)/$(am__dirstamp)
win_utf8_io/win_utf8_io.lo: win_utf8_io/$(am__dirstamp) \
win_utf8_io/$(DEPDIR)/$(am__dirstamp)
win_utf8_io/libwin_utf8_io.la: $(win_utf8_io_libwin_utf8_io_la_OBJECTS) $(win_utf8_io_libwin_utf8_io_la_DEPENDENCIES) $(EXTRA_win_utf8_io_libwin_utf8_io_la_DEPENDENCIES) win_utf8_io/$(am__dirstamp)
$(AM_V_CCLD)$(LINK) $(am_win_utf8_io_libwin_utf8_io_la_rpath) $(win_utf8_io_libwin_utf8_io_la_OBJECTS) $(win_utf8_io_libwin_utf8_io_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f getopt/*.$(OBJEXT)
-rm -f getopt/*.lo
-rm -f grabbag/*.$(OBJEXT)
-rm -f grabbag/*.lo
-rm -f replaygain_analysis/*.$(OBJEXT)
-rm -f replaygain_analysis/*.lo
-rm -f replaygain_synthesis/*.$(OBJEXT)
-rm -f replaygain_synthesis/*.lo
-rm -f utf8/*.$(OBJEXT)
-rm -f utf8/*.lo
-rm -f win_utf8_io/*.$(OBJEXT)
-rm -f win_utf8_io/*.lo
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@getopt/$(DEPDIR)/getopt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@getopt/$(DEPDIR)/getopt1.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/cuesheet.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/file.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/picture.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/replaygain.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/seektable.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@grabbag/$(DEPDIR)/snprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@replaygain_analysis/$(DEPDIR)/replaygain_analysis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utf8/$(DEPDIR)/charset.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utf8/$(DEPDIR)/iconvert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utf8/$(DEPDIR)/utf8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@win_utf8_io/$(DEPDIR)/win_utf8_io.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo: replaygain_synthesis/replaygain_synthesis.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS) $(CFLAGS) -MT replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo -MD -MP -MF replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Tpo -c -o replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo `test -f 'replaygain_synthesis/replaygain_synthesis.c' || echo '$(srcdir)/'`replaygain_synthesis/replaygain_synthesis.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Tpo replaygain_synthesis/$(DEPDIR)/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='replaygain_synthesis/replaygain_synthesis.c' object='replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(replaygain_synthesis_libreplaygain_synthesis_la_CFLAGS) $(CFLAGS) -c -o replaygain_synthesis/replaygain_synthesis_libreplaygain_synthesis_la-replaygain_synthesis.lo `test -f 'replaygain_synthesis/replaygain_synthesis.c' || echo '$(srcdir)/'`replaygain_synthesis/replaygain_synthesis.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-rm -rf getopt/.libs getopt/_libs
-rm -rf grabbag/.libs grabbag/_libs
-rm -rf replaygain_analysis/.libs replaygain_analysis/_libs
-rm -rf replaygain_synthesis/.libs replaygain_synthesis/_libs
-rm -rf utf8/.libs utf8/_libs
-rm -rf win_utf8_io/.libs win_utf8_io/_libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f getopt/$(DEPDIR)/$(am__dirstamp)
-rm -f getopt/$(am__dirstamp)
-rm -f grabbag/$(DEPDIR)/$(am__dirstamp)
-rm -f grabbag/$(am__dirstamp)
-rm -f replaygain_analysis/$(DEPDIR)/$(am__dirstamp)
-rm -f replaygain_analysis/$(am__dirstamp)
-rm -f replaygain_synthesis/$(DEPDIR)/$(am__dirstamp)
-rm -f replaygain_synthesis/$(am__dirstamp)
-rm -f utf8/$(DEPDIR)/$(am__dirstamp)
-rm -f utf8/$(am__dirstamp)
-rm -f win_utf8_io/$(DEPDIR)/$(am__dirstamp)
-rm -f win_utf8_io/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf getopt/$(DEPDIR) grabbag/$(DEPDIR) replaygain_analysis/$(DEPDIR) replaygain_synthesis/$(DEPDIR) utf8/$(DEPDIR) win_utf8_io/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf getopt/$(DEPDIR) grabbag/$(DEPDIR) replaygain_analysis/$(DEPDIR) replaygain_synthesis/$(DEPDIR) utf8/$(DEPDIR) win_utf8_io/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
debug:
$(MAKE) all CFLAGS="@DEBUG@"
profile:
$(MAKE) all CFLAGS="@PROFILE@"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,58 @@
# FLAC - Free Lossless Audio Codec
# Copyright (C) 2001-2009 Josh Coalson
# Copyright (C) 2011-2016 Xiph.Org Foundation
#
# This file is part the FLAC project. FLAC is comprised of several
# components distributed under different licenses. The codec libraries
# are distributed under Xiph.Org's BSD-like license (see the file
# COPYING.Xiph in this distribution). All other programs, libraries, and
# plugins are distributed under the GPL (see COPYING.GPL). The documentation
# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the
# FLAC distribution contains at the top the terms under which it may be
# distributed.
#
# Since this particular file is relevant to all components of FLAC,
# it may be distributed under the Xiph.Org license, which is the least
# restrictive of those mentioned above. See the file COPYING.Xiph in this
# distribution.
.PHONY: all getopt grabbag replaygain_analysis replaygain_synthesis utf8
all: getopt replaygain_analysis grabbag replaygain_synthesis utf8
DEFAULT_CONFIG = release
CONFIG = $(DEFAULT_CONFIG)
debug : CONFIG = debug
valgrind: CONFIG = valgrind
release : CONFIG = release
debug : all
valgrind: all
release : all
getopt:
(cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG))
replaygain_analysis:
(cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG))
grabbag:
(cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG))
replaygain_synthesis:
(cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG))
utf8:
(cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG))
win_utf8_io:
(cd $@ ; $(MAKE) -f Makefile.lite $(CONFIG))
clean:
-(cd getopt ; $(MAKE) -f Makefile.lite clean)
-(cd grabbag ; $(MAKE) -f Makefile.lite clean)
-(cd replaygain_analysis ; $(MAKE) -f Makefile.lite clean)
-(cd replaygain_synthesis ; $(MAKE) -f Makefile.lite clean)
-(cd utf8 ; $(MAKE) -f Makefile.lite clean)
-(cd win_utf8_io ; $(MAKE) -f Makefile.lite clean)

View File

@ -0,0 +1,5 @@
This directory contains several convenience libraries used by the rest of the
tools and plugins. Two of them (getopt and utf8) are shamelessly copied from
vorbistools, one for manipulating UTF-8 strings (GPL) and one for implementing
getopt (LGPL). libFLAC does not link to either; the only FLAC tools that do
are GPL'ed.

View File

@ -0,0 +1,16 @@
#
# GNU makefile
#
topdir = ../../..
LIB_NAME = libgetopt
INCLUDES = -I$(topdir)/include
SRCS_C = \
getopt.c \
getopt1.c
include $(topdir)/build/lib.mk
# DO NOT DELETE THIS LINE -- make depend depends on it.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,204 @@
/*
NOTE:
I cannot get the vanilla getopt code to work (i.e. compile only what
is needed and not duplicate symbols found in the standard library)
on all the platforms that FLAC supports. In particular the gating
of code with the ELIDE_CODE #define is not accurate enough on systems
that are POSIX but not glibc. If someone has a patch that works on
GNU/Linux, Darwin, AND Solaris please submit it on the project page:
https://sourceforge.net/p/flac/patches/
In the meantime I have munged the global symbols and removed gates
around code, while at the same time trying to touch the original as
little as possible.
*/
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "share/getopt.h"
/*[JEC] was:#include "getopt.h"*/
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#if 1
/*[JEC] was:#ifndef ELIDE_CODE*/
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
share__getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct share__option *long_options;
int *opt_index;
{
return share___getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like share__getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
share__getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct share__option *long_options;
int *opt_index;
{
return share___getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = share__optind ? share__optind : 1;
int option_index = 0;
static struct share__option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = share__getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (share__optarg)
printf (" with arg %s", share__optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", share__optarg);
break;
case 'd':
printf ("option d with value `%s'\n", share__optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (share__optind < argc)
{
printf ("non-option ARGV-elements: ");
while (share__optind < argc)
printf ("%s ", argv[share__optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="getopt_static"
ProjectGUID="{4cefbc80-c215-11db-8314-0800200c9a66}"
RootNamespace="getopt_static"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\getopt.c"
>
</File>
<File
RelativePath=".\getopt1.c"
>
</File>
</Filter>
<Filter
Name="Public Header Files"
>
<File
RelativePath="..\..\..\include\share\getopt.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4cefbc80-c215-11db-8314-0800200c9a66}</ProjectGuid>
<RootNamespace>getopt_static</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="getopt.c" />
<ClCompile Include="getopt1.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\getopt.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Public Header Files">
<UniqueIdentifier>{98dc8c56-677d-4f5b-9c7e-031634c635f0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="getopt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="getopt1.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\getopt.h">
<Filter>Public Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,30 @@
# grabbag - Convenience lib for various routines common to several tools
#
# GNU makefile
#
topdir = ../../..
libdir = $(topdir)/objs/$(BUILD)/lib
ifeq ($(OS),Darwin)
EXPLICIT_LIBS = $(libdir)/libFLAC.a $(libdir)/libreplaygain_analysis.a $(OGG_EXPLICIT_LIBS) -lm
else
LIBS = -lFLAC -lreplaygain_analysis $(OGG_LIBS) -lm
endif
LIB_NAME = libgrabbag
INCLUDES = -I$(topdir)/include
SRCS_C = \
alloc.c \
cuesheet.c \
file.c \
picture.c \
replaygain.c \
seektable.c \
snprintf.c
include $(topdir)/build/lib.mk
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,48 @@
/* alloc - Convenience routines for safely allocating memory
* Copyright (C) 2007-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include "share/alloc.h"
void *safe_malloc_mul_2op_(size_t size1, size_t size2)
{
if(!size1 || !size2)
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
if(size1 > SIZE_MAX / size2)
return 0;
return malloc(size1*size2);
}

View File

@ -0,0 +1,656 @@
/* grabbag - Convenience lib for various routines common to several tools
* Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FLAC/assert.h"
#include "share/compat.h"
#include "share/grabbag.h"
#include "share/safe_str.h"
unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames)
{
return ((minutes * 60) + seconds) * 75 + frames;
}
void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames)
{
*frames = frame % 75;
frame /= 75;
*seconds = frame % 60;
frame /= 60;
*minutes = frame;
}
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
static int local__parse_int_(const char *s)
{
int ret = 0;
char c;
if(*s == '\0')
return -1;
while('\0' != (c = *s++))
if(c >= '0' && c <= '9')
ret = ret * 10 + (c - '0');
else
return -1;
return ret;
}
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
static FLAC__int64 local__parse_int64_(const char *s)
{
FLAC__int64 ret = 0;
char c;
if(*s == '\0')
return -1;
while('\0' != (c = *s++))
if(c >= '0' && c <= '9')
ret = ret * 10 + (c - '0');
else
return -1;
return ret;
}
/* accept minute:second:frame syntax of '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67
* return sample number or <0 for error
* WATCHOUT: if sample rate is not evenly divisible by 75, the resulting sample number will be approximate
*/
static FLAC__int64 local__parse_msf_(const char *s, unsigned sample_rate)
{
FLAC__int64 ret, field;
char c;
c = *s++;
if(c >= '0' && c <= '9')
field = (c - '0');
else
return -1;
while(':' != (c = *s++)) {
if(c >= '0' && c <= '9')
field = field * 10 + (c - '0');
else
return -1;
}
ret = field * 60 * sample_rate;
c = *s++;
if(c >= '0' && c <= '9')
field = (c - '0');
else
return -1;
if(':' != (c = *s++)) {
if(c >= '0' && c <= '9') {
field = field * 10 + (c - '0');
c = *s++;
if(c != ':')
return -1;
}
else
return -1;
}
if(field >= 60)
return -1;
ret += field * sample_rate;
c = *s++;
if(c >= '0' && c <= '9')
field = (c - '0');
else
return -1;
if('\0' != (c = *s++)) {
if(c >= '0' && c <= '9') {
field = field * 10 + (c - '0');
c = *s++;
}
else
return -1;
}
if(c != '\0')
return -1;
if(field >= 75)
return -1;
ret += field * (sample_rate / 75);
return ret;
}
/* accept minute:second syntax of '[0-9]+:[0-9][0-9]?{,.[0-9]+}', but second < 60, e.g. 0:0.0, 3:5, 15:31.731
* return sample number or <0 for error
* WATCHOUT: depending on the sample rate, the resulting sample number may be approximate with fractional seconds
*/
static FLAC__int64 local__parse_ms_(const char *s, unsigned sample_rate)
{
FLAC__int64 ret, field;
double x;
char c, *end;
c = *s++;
if(c >= '0' && c <= '9')
field = (c - '0');
else
return -1;
while(':' != (c = *s++)) {
if(c >= '0' && c <= '9')
field = field * 10 + (c - '0');
else
return -1;
}
ret = field * 60 * sample_rate;
s++; /* skip the ':' */
if(strspn(s, "0123456789.") != strlen(s))
return -1;
x = strtod(s, &end);
if(*end || end == s)
return -1;
if(x < 0.0 || x >= 60.0)
return -1;
ret += (FLAC__int64)(x * sample_rate);
return ret;
}
static char *local__get_field_(char **s, FLAC__bool allow_quotes)
{
FLAC__bool has_quote = false;
char *p;
FLAC__ASSERT(0 != s);
if(0 == *s)
return 0;
/* skip leading whitespace */
while(**s && 0 != strchr(" \t\r\n", **s))
(*s)++;
if(**s == 0) {
*s = 0;
return 0;
}
if(allow_quotes && (**s == '"')) {
has_quote = true;
(*s)++;
if(**s == 0) {
*s = 0;
return 0;
}
}
p = *s;
if(has_quote) {
*s = strchr(*s, '\"');
/* if there is no matching end quote, it's an error */
if(0 == *s)
p = *s = 0;
else {
**s = '\0';
(*s)++;
}
}
else {
while(**s && 0 == strchr(" \t\r\n", **s))
(*s)++;
if(**s) {
**s = '\0';
(*s)++;
}
else
*s = 0;
}
return p;
}
static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
{
char buffer[4096], *line, *field;
unsigned forced_leadout_track_num = 0;
FLAC__uint64 forced_leadout_track_offset = 0;
int in_track_num = -1, in_index_num = -1;
FLAC__bool disc_has_catalog = false, track_has_flags = false, track_has_isrc = false, has_forced_leadout = false;
FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
FLAC__ASSERT(!is_cdda || sample_rate == 44100);
/* double protection */
if(is_cdda && sample_rate != 44100) {
*error_message = "CD-DA cuesheet only allowed with 44.1kHz sample rate";
return false;
}
cs->lead_in = is_cdda? 2 * 44100 /* The default lead-in size for CD-DA */ : 0;
cs->is_cd = is_cdda;
while(0 != fgets(buffer, sizeof(buffer), file)) {
(*last_line_read)++;
line = buffer;
{
size_t linelen = strlen(line);
if((linelen == sizeof(buffer)-1) && line[linelen-1] != '\n') {
*error_message = "line too long";
return false;
}
}
if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
if(0 == FLAC__STRCASECMP(field, "CATALOG")) {
if(disc_has_catalog) {
*error_message = "found multiple CATALOG commands";
return false;
}
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) {
*error_message = "CATALOG is missing catalog number";
return false;
}
if(strlen(field) >= sizeof(cs->media_catalog_number)) {
*error_message = "CATALOG number is too long";
return false;
}
if(is_cdda && (strlen(field) != 13 || strspn(field, "0123456789") != 13)) {
*error_message = "CD-DA CATALOG number must be 13 decimal digits";
return false;
}
safe_strncpy(cs->media_catalog_number, field, sizeof(cs->media_catalog_number));
disc_has_catalog = true;
}
else if(0 == FLAC__STRCASECMP(field, "FLAGS")) {
if(track_has_flags) {
*error_message = "found multiple FLAGS commands";
return false;
}
if(in_track_num < 0 || in_index_num >= 0) {
*error_message = "FLAGS command must come after TRACK but before INDEX";
return false;
}
while(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
if(0 == FLAC__STRCASECMP(field, "PRE"))
cs->tracks[cs->num_tracks-1].pre_emphasis = 1;
}
track_has_flags = true;
}
else if(0 == FLAC__STRCASECMP(field, "INDEX")) {
FLAC__int64 xx;
FLAC__StreamMetadata_CueSheet_Track *track = &cs->tracks[cs->num_tracks-1];
if(in_track_num < 0) {
*error_message = "found INDEX before any TRACK";
return false;
}
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "INDEX is missing index number";
return false;
}
in_index_num = local__parse_int_(field);
if(in_index_num < 0) {
*error_message = "INDEX has invalid index number";
return false;
}
FLAC__ASSERT(cs->num_tracks > 0);
if(track->num_indices == 0) {
/* it's the first index point of the track */
if(in_index_num > 1) {
*error_message = "first INDEX number of a TRACK must be 0 or 1";
return false;
}
}
else {
if(in_index_num != track->indices[track->num_indices-1].number + 1) {
*error_message = "INDEX numbers must be sequential";
return false;
}
}
if(is_cdda && in_index_num > 99) {
*error_message = "CD-DA INDEX number must be between 0 and 99, inclusive";
return false;
}
/*@@@ search for duplicate track number? */
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "INDEX is missing an offset after the index number";
return false;
}
/* first parse as minute:second:frame format */
xx = local__parse_msf_(field, sample_rate);
if(xx < 0) {
/* CD-DA must use only MM:SS:FF format */
if(is_cdda) {
*error_message = "illegal INDEX offset (not of the form MM:SS:FF)";
return false;
}
/* as an extension for non-CD-DA we allow MM:SS.SS or raw sample number */
xx = local__parse_ms_(field, sample_rate);
if(xx < 0) {
xx = local__parse_int64_(field);
if(xx < 0) {
*error_message = "illegal INDEX offset";
return false;
}
}
}
else if(sample_rate % 75 && xx) {
/* only sample zero is exact */
*error_message = "illegal INDEX offset (MM:SS:FF form not allowed if sample rate is not a multiple of 75)";
return false;
}
if(is_cdda && cs->num_tracks == 1 && cs->tracks[0].num_indices == 0 && xx != 0) {
*error_message = "first INDEX of first TRACK must have an offset of 00:00:00";
return false;
}
if(is_cdda && track->num_indices > 0 && (FLAC__uint64)xx <= track->indices[track->num_indices-1].offset) {
*error_message = "CD-DA INDEX offsets must increase in time";
return false;
}
/* fill in track offset if it's the first index of the track */
if(track->num_indices == 0)
track->offset = (FLAC__uint64)xx;
if(is_cdda && cs->num_tracks > 1) {
const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-2];
if((FLAC__uint64)xx <= prev->offset + prev->indices[prev->num_indices-1].offset) {
*error_message = "CD-DA INDEX offsets must increase in time";
return false;
}
}
if(!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, cs->num_tracks-1, track->num_indices)) {
*error_message = "memory allocation error";
return false;
}
track->indices[track->num_indices-1].offset = (FLAC__uint64)xx - track->offset;
track->indices[track->num_indices-1].number = in_index_num;
}
else if(0 == FLAC__STRCASECMP(field, "ISRC")) {
char *l, *r;
if(track_has_isrc) {
*error_message = "found multiple ISRC commands";
return false;
}
if(in_track_num < 0 || in_index_num >= 0) {
*error_message = "ISRC command must come after TRACK but before INDEX";
return false;
}
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) {
*error_message = "ISRC is missing ISRC number";
return false;
}
/* strip out dashes */
for(l = r = field; *r; r++) {
if(*r != '-')
*l++ = *r;
}
*l = '\0';
if(strlen(field) != 12 || strspn(field, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") < 5 || strspn(field+5, "1234567890") != 7) {
*error_message = "invalid ISRC number";
return false;
}
safe_strncpy(cs->tracks[cs->num_tracks-1].isrc, field, sizeof(cs->tracks[cs->num_tracks-1].isrc));
track_has_isrc = true;
}
else if(0 == FLAC__STRCASECMP(field, "TRACK")) {
if(cs->num_tracks > 0) {
const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-1];
if(
prev->num_indices == 0 ||
(
is_cdda &&
(
(prev->num_indices == 1 && prev->indices[0].number != 1) ||
(prev->num_indices == 2 && prev->indices[0].number != 1 && prev->indices[1].number != 1)
)
)
) {
*error_message = is_cdda?
"previous TRACK must specify at least one INDEX 01" :
"previous TRACK must specify at least one INDEX";
return false;
}
}
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "TRACK is missing track number";
return false;
}
in_track_num = local__parse_int_(field);
if(in_track_num < 0) {
*error_message = "TRACK has invalid track number";
return false;
}
if(in_track_num == 0) {
*error_message = "TRACK number must be greater than 0";
return false;
}
if(is_cdda) {
if(in_track_num > 99) {
*error_message = "CD-DA TRACK number must be between 1 and 99, inclusive";
return false;
}
}
else {
if(in_track_num == 255) {
*error_message = "TRACK number 255 is reserved for the lead-out";
return false;
}
else if(in_track_num > 255) {
*error_message = "TRACK number must be between 1 and 254, inclusive";
return false;
}
}
if(is_cdda && cs->num_tracks > 0 && in_track_num != cs->tracks[cs->num_tracks-1].number + 1) {
*error_message = "CD-DA TRACK numbers must be sequential";
return false;
}
/*@@@ search for duplicate track number? */
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "TRACK is missing a track type after the track number";
return false;
}
if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) {
*error_message = "memory allocation error";
return false;
}
cs->tracks[cs->num_tracks-1].number = in_track_num;
cs->tracks[cs->num_tracks-1].type = (0 == FLAC__STRCASECMP(field, "AUDIO"))? 0 : 1; /*@@@ should we be more strict with the value here? */
in_index_num = -1;
track_has_flags = false;
track_has_isrc = false;
}
else if(0 == FLAC__STRCASECMP(field, "REM")) {
if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
if(0 == strcmp(field, "FLAC__lead-in")) {
FLAC__int64 xx;
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "FLAC__lead-in is missing offset";
return false;
}
xx = local__parse_int64_(field);
if(xx < 0) {
*error_message = "illegal FLAC__lead-in offset";
return false;
}
if(is_cdda && xx % 588 != 0) {
*error_message = "illegal CD-DA FLAC__lead-in offset, must be even multiple of 588 samples";
return false;
}
cs->lead_in = (FLAC__uint64)xx;
}
else if(0 == strcmp(field, "FLAC__lead-out")) {
int track_num;
FLAC__int64 offset;
if(has_forced_leadout) {
*error_message = "multiple FLAC__lead-out commands";
return false;
}
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "FLAC__lead-out is missing track number";
return false;
}
track_num = local__parse_int_(field);
if(track_num < 0) {
*error_message = "illegal FLAC__lead-out track number";
return false;
}
forced_leadout_track_num = (unsigned)track_num;
/*@@@ search for duplicate track number? */
if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
*error_message = "FLAC__lead-out is missing offset";
return false;
}
offset = local__parse_int64_(field);
if(offset < 0) {
*error_message = "illegal FLAC__lead-out offset";
return false;
}
forced_leadout_track_offset = (FLAC__uint64)offset;
if(forced_leadout_track_offset != lead_out_offset) {
*error_message = "FLAC__lead-out offset does not match end-of-stream offset";
return false;
}
has_forced_leadout = true;
}
}
}
}
}
if(cs->num_tracks == 0) {
*error_message = "there must be at least one TRACK command";
return false;
}
else {
const FLAC__StreamMetadata_CueSheet_Track *prev = &cs->tracks[cs->num_tracks-1];
if(
prev->num_indices == 0 ||
(
is_cdda &&
(
(prev->num_indices == 1 && prev->indices[0].number != 1) ||
(prev->num_indices == 2 && prev->indices[0].number != 1 && prev->indices[1].number != 1)
)
)
) {
*error_message = is_cdda?
"previous TRACK must specify at least one INDEX 01" :
"previous TRACK must specify at least one INDEX";
return false;
}
}
if(!has_forced_leadout) {
forced_leadout_track_num = is_cdda? 170 : 255;
forced_leadout_track_offset = lead_out_offset;
}
if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) {
*error_message = "memory allocation error";
return false;
}
cs->tracks[cs->num_tracks-1].number = forced_leadout_track_num;
cs->tracks[cs->num_tracks-1].offset = forced_leadout_track_offset;
if(!feof(file)) {
*error_message = "read error";
return false;
}
return true;
}
FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
{
FLAC__StreamMetadata *cuesheet;
FLAC__ASSERT(0 != file);
FLAC__ASSERT(0 != error_message);
FLAC__ASSERT(0 != last_line_read);
*last_line_read = 0;
cuesheet = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET);
if(0 == cuesheet) {
*error_message = "memory allocation error";
return 0;
}
if(!local__cuesheet_parse_(file, error_message, last_line_read, cuesheet, sample_rate, is_cdda, lead_out_offset)) {
FLAC__metadata_object_delete(cuesheet);
return 0;
}
return cuesheet;
}
void grabbag__cuesheet_emit(FILE *file, const FLAC__StreamMetadata *cuesheet, const char *file_reference)
{
const FLAC__StreamMetadata_CueSheet *cs;
unsigned track_num, index_num;
FLAC__ASSERT(0 != file);
FLAC__ASSERT(0 != cuesheet);
FLAC__ASSERT(cuesheet->type == FLAC__METADATA_TYPE_CUESHEET);
cs = &cuesheet->data.cue_sheet;
if(*(cs->media_catalog_number))
fprintf(file, "CATALOG %s\n", cs->media_catalog_number);
fprintf(file, "FILE %s\n", file_reference);
for(track_num = 0; track_num < cs->num_tracks-1; track_num++) {
const FLAC__StreamMetadata_CueSheet_Track *track = cs->tracks + track_num;
fprintf(file, " TRACK %02u %s\n", (unsigned)track->number, track->type == 0? "AUDIO" : "DATA");
if(track->pre_emphasis)
fprintf(file, " FLAGS PRE\n");
if(*(track->isrc))
fprintf(file, " ISRC %s\n", track->isrc);
for(index_num = 0; index_num < track->num_indices; index_num++) {
const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + index_num;
fprintf(file, " INDEX %02u ", (unsigned)indx->number);
if(cs->is_cd) {
const unsigned logical_frame = (unsigned)((track->offset + indx->offset) / (44100 / 75));
unsigned m, s, f;
grabbag__cuesheet_frame_to_msf(logical_frame, &m, &s, &f);
fprintf(file, "%02u:%02u:%02u\n", m, s, f);
}
else
fprintf(file, "%" PRIu64 "\n", (track->offset + indx->offset));
}
}
fprintf(file, "REM FLAC__lead-in %" PRIu64 "\n", cs->lead_in);
fprintf(file, "REM FLAC__lead-out %u %" PRIu64 "\n", (unsigned)cs->tracks[track_num].number, cs->tracks[track_num].offset);
}

View File

@ -0,0 +1,193 @@
/* grabbag - Convenience lib for various routines common to several tools
* Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if defined _MSC_VER || defined __MINGW32__
#include <sys/utime.h> /* for utime() */
#include <io.h> /* for chmod(), _setmode(), unlink() */
#include <fcntl.h> /* for _O_BINARY */
#else
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
#include <utime.h> /* for utime() */
#endif
#if defined __CYGWIN__ || defined __EMX__
#include <io.h> /* for setmode(), O_BINARY */
#include <fcntl.h> /* for _O_BINARY */
#endif
#include <sys/stat.h> /* for stat(), maybe chmod() */
#if defined _WIN32 && !defined __CYGWIN__
#else
#include <unistd.h> /* for unlink() */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for strrchr() */
#if defined _WIN32 && !defined __CYGWIN__
// for GetFileInformationByHandle() etc
#include <windows.h>
#include <winbase.h>
#endif
#include "share/grabbag.h"
void grabbag__file_copy_metadata(const char *srcpath, const char *destpath)
{
struct flac_stat_s srcstat;
struct utimbuf srctime;
if(0 == flac_stat(srcpath, &srcstat)) {
srctime.actime = srcstat.st_atime;
srctime.modtime = srcstat.st_mtime;
(void)flac_chmod(destpath, srcstat.st_mode);
(void)flac_utime(destpath, &srctime);
}
}
FLAC__off_t grabbag__file_get_filesize(const char *srcpath)
{
struct flac_stat_s srcstat;
if(0 == flac_stat(srcpath, &srcstat))
return srcstat.st_size;
else
return -1;
}
const char *grabbag__file_get_basename(const char *srcpath)
{
const char *p;
p = strrchr(srcpath, '/');
if(0 == p) {
p = strrchr(srcpath, '\\');
if(0 == p)
return srcpath;
}
return ++p;
}
FLAC__bool grabbag__file_change_stats(const char *filename, FLAC__bool read_only)
{
struct flac_stat_s stats;
if(0 == flac_stat(filename, &stats)) {
#if !defined _MSC_VER && !defined __MINGW32__
if(read_only) {
stats.st_mode &= ~S_IWUSR;
stats.st_mode &= ~S_IWGRP;
stats.st_mode &= ~S_IWOTH;
}
else {
stats.st_mode |= S_IWUSR;
}
#else
if(read_only)
stats.st_mode &= ~S_IWRITE;
else
stats.st_mode |= S_IWRITE;
#endif
if(0 != flac_chmod(filename, stats.st_mode))
return false;
}
else
return false;
return true;
}
FLAC__bool grabbag__file_are_same(const char *f1, const char *f2)
{
#if defined _MSC_VER || defined __MINGW32__
/* see
* http://www.hydrogenaudio.org/forums/index.php?showtopic=49439&pid=444300&st=0
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileinformationbyhandle.asp
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/by_handle_file_information_str.asp
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp
* apparently both the files have to be open at the same time for the comparison to work
*/
FLAC__bool same = false;
BY_HANDLE_FILE_INFORMATION info1, info2;
HANDLE h1, h2;
BOOL ok = 1;
h1 = CreateFile_utf8(f1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
h2 = CreateFile_utf8(f2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE)
ok = 0;
ok &= GetFileInformationByHandle(h1, &info1);
ok &= GetFileInformationByHandle(h2, &info2);
if(ok)
same =
info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber &&
info1.nFileIndexHigh == info2.nFileIndexHigh &&
info1.nFileIndexLow == info2.nFileIndexLow
;
if(h1 != INVALID_HANDLE_VALUE)
CloseHandle(h1);
if(h2 != INVALID_HANDLE_VALUE)
CloseHandle(h2);
return same;
#else
struct flac_stat_s s1, s2;
return f1 && f2 && flac_stat(f1, &s1) == 0 && flac_stat(f2, &s2) == 0 && s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev;
#endif
}
FLAC__bool grabbag__file_remove_file(const char *filename)
{
return grabbag__file_change_stats(filename, /*read_only=*/false) && 0 == flac_unlink(filename);
}
FILE *grabbag__file_get_binary_stdin(void)
{
/* if something breaks here it is probably due to the presence or
* absence of an underscore before the identifiers 'setmode',
* 'fileno', and/or 'O_BINARY'; check your system header files.
*/
#if defined _MSC_VER || defined __MINGW32__
_setmode(_fileno(stdin), _O_BINARY);
#elif defined __CYGWIN__
/* almost certainly not needed for any modern Cygwin, but let's be safe... */
setmode(_fileno(stdin), _O_BINARY);
#elif defined __EMX__
setmode(fileno(stdin), O_BINARY);
#endif
return stdin;
}
FILE *grabbag__file_get_binary_stdout(void)
{
/* if something breaks here it is probably due to the presence or
* absence of an underscore before the identifiers 'setmode',
* 'fileno', and/or 'O_BINARY'; check your system header files.
*/
#if defined _MSC_VER || defined __MINGW32__
_setmode(_fileno(stdout), _O_BINARY);
#elif defined __CYGWIN__
/* almost certainly not needed for any modern Cygwin, but let's be safe... */
setmode(_fileno(stdout), _O_BINARY);
#elif defined __EMX__
setmode(fileno(stdout), O_BINARY);
#endif
return stdout;
}

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="grabbag_static"
ProjectGUID="{4cefbc81-c215-11db-8314-0800200c9a66}"
RootNamespace="grabbag_static"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\alloc.c"
>
</File>
<File
RelativePath=".\cuesheet.c"
>
</File>
<File
RelativePath=".\file.c"
>
</File>
<File
RelativePath=".\picture.c"
>
</File>
<File
RelativePath=".\replaygain.c"
>
</File>
<File
RelativePath=".\seektable.c"
>
</File>
<File
RelativePath=".\snprintf.c"
>
</File>
</Filter>
<Filter
Name="Public Header Files"
>
<File
RelativePath="..\..\..\include\share\grabbag.h"
>
</File>
<Filter
Name="grabbag"
>
<File
RelativePath="..\..\..\include\share\grabbag\cuesheet.h"
>
</File>
<File
RelativePath="..\..\..\include\share\grabbag\file.h"
>
</File>
<File
RelativePath="..\..\..\include\share\grabbag\picture.h"
>
</File>
<File
RelativePath="..\..\..\include\share\grabbag\replaygain.h"
>
</File>
<File
RelativePath="..\..\..\include\share\grabbag\seektable.h"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4cefbc81-c215-11db-8314-0800200c9a66}</ProjectGuid>
<RootNamespace>grabbag_static</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="alloc.c" />
<ClCompile Include="cuesheet.c" />
<ClCompile Include="file.c" />
<ClCompile Include="picture.c" />
<ClCompile Include="replaygain.c" />
<ClCompile Include="seektable.c" />
<ClCompile Include="snprintf.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\grabbag.h" />
<ClInclude Include="..\..\..\include\share\grabbag\cuesheet.h" />
<ClInclude Include="..\..\..\include\share\grabbag\file.h" />
<ClInclude Include="..\..\..\include\share\grabbag\picture.h" />
<ClInclude Include="..\..\..\include\share\grabbag\replaygain.h" />
<ClInclude Include="..\..\..\include\share\grabbag\seektable.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libFLAC\libFLAC_static.vcxproj">
<Project>{4cefbc84-c215-11db-8314-0800200c9a66}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\replaygain_analysis\replaygain_analysis_static.vcxproj">
<Project>{4cefbc89-c215-11db-8314-0800200c9a66}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Public Header Files">
<UniqueIdentifier>{d4e83ff0-6406-4b76-bd64-6192e6b8e47a}</UniqueIdentifier>
</Filter>
<Filter Include="Public Header Files\grabbag">
<UniqueIdentifier>{82df5da8-3a2c-402e-a7cd-a88de1a7be91}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="alloc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cuesheet.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="file.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="picture.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="replaygain.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seektable.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="snprintf.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\grabbag.h">
<Filter>Public Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\include\share\grabbag\cuesheet.h">
<Filter>Public Header Files\grabbag</Filter>
</ClInclude>
<ClInclude Include="..\..\..\include\share\grabbag\file.h">
<Filter>Public Header Files\grabbag</Filter>
</ClInclude>
<ClInclude Include="..\..\..\include\share\grabbag\picture.h">
<Filter>Public Header Files\grabbag</Filter>
</ClInclude>
<ClInclude Include="..\..\..\include\share\grabbag\replaygain.h">
<Filter>Public Header Files\grabbag</Filter>
</ClInclude>
<ClInclude Include="..\..\..\include\share\grabbag\seektable.h">
<Filter>Public Header Files\grabbag</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,508 @@
/* grabbag - Convenience lib for various routines common to several tools
* Copyright (C) 2006-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "share/alloc.h"
#include "share/grabbag.h"
#include "FLAC/assert.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "share/compat.h"
#include "share/safe_str.h"
/* slightly different that strndup(): this always copies 'size' bytes starting from s into a NUL-terminated string. */
static char *local__strndup_(const char *s, size_t size)
{
char *x = safe_malloc_add_2op_(size, /*+*/1);
if(x) {
memcpy(x, s, size);
x[size] = '\0';
}
return x;
}
static FLAC__bool local__parse_type_(const char *s, size_t len, FLAC__StreamMetadata_Picture *picture)
{
size_t i;
FLAC__uint32 val = 0;
picture->type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
if(len == 0)
return true; /* empty string implies default to 'front cover' */
for(i = 0; i < len; i++) {
if(s[i] >= '0' && s[i] <= '9')
val = 10*val + (FLAC__uint32)(s[i] - '0');
else
return false;
}
if(i == len)
picture->type = val;
else
return false;
return true;
}
static FLAC__bool local__parse_resolution_(const char *s, size_t len, FLAC__StreamMetadata_Picture *picture)
{
int state = 0;
size_t i;
FLAC__uint32 val = 0;
picture->width = picture->height = picture->depth = picture->colors = 0;
if(len == 0)
return true; /* empty string implies client wants to get info from the file itself */
for(i = 0; i < len; i++) {
if(s[i] == 'x') {
if(state == 0)
picture->width = val;
else if(state == 1)
picture->height = val;
else
return false;
state++;
val = 0;
}
else if(s[i] == '/') {
if(state == 2)
picture->depth = val;
else
return false;
state++;
val = 0;
}
else if(s[i] >= '0' && s[i] <= '9')
val = 10*val + (FLAC__uint32)(s[i] - '0');
else
return false;
}
if(state < 2)
return false;
else if(state == 2)
picture->depth = val;
else if(state == 3)
picture->colors = val;
else
return false;
if(picture->depth < 32 && 1u<<picture->depth < picture->colors)
return false;
return true;
}
static FLAC__bool local__extract_mime_type_(FLAC__StreamMetadata *obj)
{
if(obj->data.picture.data_length >= 8 && 0 == memcmp(obj->data.picture.data, "\x89PNG\x0d\x0a\x1a\x0a", 8))
return FLAC__metadata_object_picture_set_mime_type(obj, "image/png", /*copy=*/true);
else if(obj->data.picture.data_length >= 6 && (0 == memcmp(obj->data.picture.data, "GIF87a", 6) || 0 == memcmp(obj->data.picture.data, "GIF89a", 6)))
return FLAC__metadata_object_picture_set_mime_type(obj, "image/gif", /*copy=*/true);
else if(obj->data.picture.data_length >= 2 && 0 == memcmp(obj->data.picture.data, "\xff\xd8", 2))
return FLAC__metadata_object_picture_set_mime_type(obj, "image/jpeg", /*copy=*/true);
return false;
}
static FLAC__bool local__extract_resolution_color_info_(FLAC__StreamMetadata_Picture *picture)
{
const FLAC__byte *data = picture->data;
FLAC__uint32 len = picture->data_length;
if(0 == strcmp(picture->mime_type, "image/png")) {
/* c.f. http://www.w3.org/TR/PNG/ */
FLAC__bool need_palette = false; /* if IHDR has color_type=3, we need to also read the PLTE chunk to get the #colors */
if(len < 8 || memcmp(data, "\x89PNG\x0d\x0a\x1a\x0a", 8))
return false;
/* try to find IHDR chunk */
data += 8;
len -= 8;
while(len > 12) { /* every PNG chunk must be at least 12 bytes long */
const FLAC__uint32 clen = (FLAC__uint32)data[0] << 24 | (FLAC__uint32)data[1] << 16 | (FLAC__uint32)data[2] << 8 | (FLAC__uint32)data[3];
if(0 == memcmp(data+4, "IHDR", 4) && clen == 13) {
unsigned color_type = data[17];
picture->width = (FLAC__uint32)data[8] << 24 | (FLAC__uint32)data[9] << 16 | (FLAC__uint32)data[10] << 8 | (FLAC__uint32)data[11];
picture->height = (FLAC__uint32)data[12] << 24 | (FLAC__uint32)data[13] << 16 | (FLAC__uint32)data[14] << 8 | (FLAC__uint32)data[15];
if(color_type == 3) {
/* even though the bit depth for color_type==3 can be 1,2,4,or 8,
* the spec in 11.2.2 of http://www.w3.org/TR/PNG/ says that the
* sample depth is always 8
*/
picture->depth = 8 * 3u;
need_palette = true;
data += 12 + clen;
len -= 12 + clen;
}
else {
if(color_type == 0) /* greyscale, 1 sample per pixel */
picture->depth = (FLAC__uint32)data[16];
if(color_type == 2) /* truecolor, 3 samples per pixel */
picture->depth = (FLAC__uint32)data[16] * 3u;
if(color_type == 4) /* greyscale+alpha, 2 samples per pixel */
picture->depth = (FLAC__uint32)data[16] * 2u;
if(color_type == 6) /* truecolor+alpha, 4 samples per pixel */
picture->depth = (FLAC__uint32)data[16] * 4u;
picture->colors = 0;
return true;
}
}
else if(need_palette && 0 == memcmp(data+4, "PLTE", 4)) {
picture->colors = clen / 3u;
return true;
}
else if(clen + 12 > len)
return false;
else {
data += 12 + clen;
len -= 12 + clen;
}
}
}
else if(0 == strcmp(picture->mime_type, "image/jpeg")) {
/* c.f. http://www.w3.org/Graphics/JPEG/itu-t81.pdf and Q22 of http://www.faqs.org/faqs/jpeg-faq/part1/ */
if(len < 2 || memcmp(data, "\xff\xd8", 2))
return false;
data += 2;
len -= 2;
while(1) {
/* look for sync FF byte */
for( ; len > 0; data++, len--) {
if(*data == 0xff)
break;
}
if(len == 0)
return false;
/* eat any extra pad FF bytes before marker */
for( ; len > 0; data++, len--) {
if(*data != 0xff)
break;
}
if(len == 0)
return false;
/* if we hit SOS or EOI, bail */
if(*data == 0xda || *data == 0xd9)
return false;
/* looking for some SOFn */
else if(memchr("\xc0\xc1\xc2\xc3\xc5\xc6\xc7\xc9\xca\xcb\xcd\xce\xcf", *data, 13)) {
data++; len--; /* skip marker byte */
if(len < 2)
return false;
else {
const FLAC__uint32 clen = (FLAC__uint32)data[0] << 8 | (FLAC__uint32)data[1];
if(clen < 8 || len < clen)
return false;
picture->width = (FLAC__uint32)data[5] << 8 | (FLAC__uint32)data[6];
picture->height = (FLAC__uint32)data[3] << 8 | (FLAC__uint32)data[4];
picture->depth = (FLAC__uint32)data[2] * (FLAC__uint32)data[7];
picture->colors = 0;
return true;
}
}
/* else skip it */
else {
data++; len--; /* skip marker byte */
if(len < 2)
return false;
else {
const FLAC__uint32 clen = (FLAC__uint32)data[0] << 8 | (FLAC__uint32)data[1];
if(clen < 2 || len < clen)
return false;
data += clen;
len -= clen;
}
}
}
}
else if(0 == strcmp(picture->mime_type, "image/gif")) {
/* c.f. http://www.w3.org/Graphics/GIF/spec-gif89a.txt */
if(len < 14)
return false;
if(memcmp(data, "GIF87a", 6) && memcmp(data, "GIF89a", 6))
return false;
#if 0
/* according to the GIF spec, even if the GCTF is 0, the low 3 bits should still tell the total # colors used */
if(data[10] & 0x80 == 0)
return false;
#endif
picture->width = (FLAC__uint32)data[6] | ((FLAC__uint32)data[7] << 8);
picture->height = (FLAC__uint32)data[8] | ((FLAC__uint32)data[9] << 8);
#if 0
/* this value doesn't seem to be reliable... */
picture->depth = (((FLAC__uint32)(data[10] & 0x70) >> 4) + 1) * 3u;
#else
/* ...just pessimistically assume it's 24-bit color without scanning all the color tables */
picture->depth = 8u * 3u;
#endif
picture->colors = 1u << ((FLAC__uint32)(data[10] & 0x07) + 1u);
return true;
}
return false;
}
static const char *error_messages[] = {
"memory allocation error",
"invalid picture specification",
"invalid picture specification: can't parse resolution/color part",
"unable to extract resolution and color info from URL, user must set explicitly",
"unable to extract resolution and color info from file, user must set explicitly",
"error opening picture file",
"error reading picture file",
"invalid picture type",
"unable to guess MIME type from file, user must set explicitly",
"type 1 icon must be a 32x32 pixel PNG",
"file not found", /* currently unused */
"file is too large"
};
static const char * read_file (const char * filepath, FLAC__StreamMetadata * obj)
{
const FLAC__off_t size = grabbag__file_get_filesize(filepath);
FLAC__byte *buffer;
FILE *file;
const char *error_message=NULL;
if (size < 0)
return error_messages[5];
if (size >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) /* actual limit is less because of other fields in the PICTURE metadata block */
return error_messages[11];
if ((buffer = safe_malloc_(size)) == NULL)
return error_messages[0];
if ((file = flac_fopen(filepath, "rb")) == NULL) {
free(buffer);
return error_messages[5];
}
if (fread(buffer, 1, size, file) != (size_t) size) {
fclose(file);
free(buffer);
return error_messages[6];
}
fclose(file);
if (!FLAC__metadata_object_picture_set_data(obj, buffer, size, /*copy=*/false))
error_message = error_messages[6];
/* try to extract MIME type if user left it blank */
else if (*obj->data.picture.mime_type == '\0' && !local__extract_mime_type_(obj))
error_message = error_messages[8];
/* try to extract resolution/color info if user left it blank */
else if ((obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0) && !local__extract_resolution_color_info_(&obj->data.picture))
error_message = error_messages[4];
/* check metadata block size */
else if (obj->length >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN))
error_message = error_messages[11];
return error_message;
}
FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, const char **error_message)
{
FLAC__StreamMetadata *obj;
int state = 0;
FLAC__ASSERT(0 != spec);
FLAC__ASSERT(0 != error_message);
/* double protection */
if(0 == spec)
return 0;
if(0 == error_message)
return 0;
*error_message = 0;
if(0 == (obj = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE))) {
*error_message = error_messages[0];
return obj;
}
if(strchr(spec, '|')) { /* full format */
const char *p;
char *q;
for(p = spec; *error_message==0 && *p; ) {
if(*p == '|') {
switch(state) {
case 0: /* type */
if(!local__parse_type_(spec, p-spec, &obj->data.picture))
*error_message = error_messages[7];
break;
case 1: /* mime type */
if(p-spec) { /* if blank, we'll try to guess later from the picture data */
if(0 == (q = local__strndup_(spec, p-spec)))
*error_message = error_messages[0];
else if(!FLAC__metadata_object_picture_set_mime_type(obj, q, /*copy=*/false))
*error_message = error_messages[0];
}
break;
case 2: /* description */
if(0 == (q = local__strndup_(spec, p-spec)))
*error_message = error_messages[0];
else if(!FLAC__metadata_object_picture_set_description(obj, (FLAC__byte*)q, /*copy=*/false))
*error_message = error_messages[0];
break;
case 3: /* resolution/color (e.g. [300x300x16[/1234]] */
if(!local__parse_resolution_(spec, p-spec, &obj->data.picture))
*error_message = error_messages[2];
break;
default:
*error_message = error_messages[1];
break;
}
p++;
spec = p;
state++;
}
else
p++;
}
}
else { /* simple format, filename only, everything else guessed */
if(!local__parse_type_("", 0, &obj->data.picture)) /* use default picture type */
*error_message = error_messages[7];
/* leave MIME type to be filled in later */
/* leave description empty */
/* leave the rest to be filled in later: */
else if(!local__parse_resolution_("", 0, &obj->data.picture))
*error_message = error_messages[2];
else
state = 4;
}
/* parse filename, read file, try to extract resolution/color info if needed */
if(*error_message == 0) {
if(state != 4)
*error_message = error_messages[1];
else { /* 'spec' points to filename/URL */
if(0 == strcmp(obj->data.picture.mime_type, "-->")) { /* magic MIME type means URL */
if(!FLAC__metadata_object_picture_set_data(obj, (FLAC__byte*)spec, strlen(spec), /*copy=*/true))
*error_message = error_messages[0];
else if(obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0)
*error_message = error_messages[3];
}
else { /* regular picture file */
*error_message = read_file (spec, obj);
}
}
}
if(*error_message == 0) {
if(
obj->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD &&
(
(strcmp(obj->data.picture.mime_type, "image/png") && strcmp(obj->data.picture.mime_type, "-->")) ||
obj->data.picture.width != 32 ||
obj->data.picture.height != 32
)
)
*error_message = error_messages[9];
}
if(*error_message && obj) {
FLAC__metadata_object_delete(obj);
obj = 0;
}
return obj;
}
FLAC__StreamMetadata *grabbag__picture_from_specification(int type, const char *mime_type_in, const char * description,
const PictureResolution * res, const char * filepath, const char **error_message)
{
FLAC__StreamMetadata *obj;
char mime_type [64] ;
if (error_message == 0)
return 0;
safe_strncpy(mime_type, mime_type_in, sizeof (mime_type));
*error_message = 0;
if ((obj = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE)) == 0) {
*error_message = error_messages[0];
return obj;
}
/* Picture type if known. */
obj->data.picture.type = type >= 0 ? type : FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
/* Mime type if known. */
if (mime_type_in && ! FLAC__metadata_object_picture_set_mime_type(obj, mime_type, /*copy=*/true)) {
*error_message = error_messages[0];
return obj;
}
/* Description if present. */
if (description && ! FLAC__metadata_object_picture_set_description(obj, (FLAC__byte*) description, /*copy=*/true)) {
*error_message = error_messages[0];
return obj;
}
if (res == NULL) {
obj->data.picture.width = 0;
obj->data.picture.height = 0;
obj->data.picture.depth = 0;
obj->data.picture.colors = 0;
}
else {
obj->data.picture.width = res->width;
obj->data.picture.height = res->height;
obj->data.picture.depth = res->depth;
obj->data.picture.colors = res->colors;
}
if (strcmp(obj->data.picture.mime_type, "-->") == 0) { /* magic MIME type means URL */
if (!FLAC__metadata_object_picture_set_data(obj, (FLAC__byte*)filepath, strlen(filepath), /*copy=*/true))
*error_message = error_messages[0];
else if (obj->data.picture.width == 0 || obj->data.picture.height == 0 || obj->data.picture.depth == 0)
*error_message = error_messages[3];
}
else {
*error_message = read_file (filepath, obj);
}
if (*error_message == NULL) {
if (
obj->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD &&
(
(strcmp(obj->data.picture.mime_type, "image/png") && strcmp(obj->data.picture.mime_type, "-->")) ||
obj->data.picture.width != 32 ||
obj->data.picture.height != 32
)
)
*error_message = error_messages[9];
}
if (*error_message && obj) {
FLAC__metadata_object_delete(obj);
obj = 0;
}
return obj;
}

View File

@ -0,0 +1,668 @@
/* grabbag - Convenience lib for various routines common to several tools
* Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <locale.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined _MSC_VER || defined __MINGW32__
#include <io.h> /* for chmod() */
#endif
#include <sys/stat.h> /* for stat(), maybe chmod() */
#include "FLAC/assert.h"
#include "FLAC/metadata.h"
#include "FLAC/stream_decoder.h"
#include "share/grabbag.h"
#include "share/replaygain_analysis.h"
#include "share/safe_str.h"
#ifdef local_min
#undef local_min
#endif
#define local_min(a,b) ((a)<(b)?(a):(b))
#ifdef local_max
#undef local_max
#endif
#define local_max(a,b) ((a)>(b)?(a):(b))
static const char *reference_format_ = "%s=%2.1f dB";
static const char *gain_format_ = "%s=%+2.2f dB";
static const char *peak_format_ = "%s=%1.8f";
static double album_peak_, title_peak_;
const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED = 190;
/*
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 29 + 1 + 8 +
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 +
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12 +
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 +
FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12
*/
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS = (const FLAC__byte * const)"REPLAYGAIN_REFERENCE_LOUDNESS";
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN = (const FLAC__byte * const)"REPLAYGAIN_TRACK_GAIN";
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK = (const FLAC__byte * const)"REPLAYGAIN_TRACK_PEAK";
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_GAIN";
const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_PEAK";
static FLAC__bool get_file_stats_(const char *filename, struct flac_stat_s *stats)
{
FLAC__ASSERT(0 != filename);
FLAC__ASSERT(0 != stats);
return (0 == flac_stat(filename, stats));
}
static void set_file_stats_(const char *filename, struct flac_stat_s *stats)
{
FLAC__ASSERT(0 != filename);
FLAC__ASSERT(0 != stats);
(void)flac_chmod(filename, stats->st_mode);
}
static FLAC__bool append_tag_(FLAC__StreamMetadata *block, const char *format, const FLAC__byte *name, float value)
{
char buffer[256];
char *saved_locale;
FLAC__StreamMetadata_VorbisComment_Entry entry;
FLAC__ASSERT(0 != block);
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
FLAC__ASSERT(0 != format);
FLAC__ASSERT(0 != name);
buffer[sizeof(buffer)-1] = '\0';
/*
* We need to save the old locale and switch to "C" because the locale
* influences the formatting of %f and we want it a certain way.
*/
saved_locale = strdup(setlocale(LC_ALL, 0));
if (0 == saved_locale)
return false;
setlocale(LC_ALL, "C");
flac_snprintf(buffer, sizeof(buffer), format, name, value);
setlocale(LC_ALL, saved_locale);
free(saved_locale);
entry.entry = (FLAC__byte *)buffer;
entry.length = strlen(buffer);
return FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true);
}
FLAC__bool grabbag__replaygain_is_valid_sample_frequency(unsigned sample_frequency)
{
return ValidGainFrequency( sample_frequency );
}
FLAC__bool grabbag__replaygain_init(unsigned sample_frequency)
{
title_peak_ = album_peak_ = 0.0;
return InitGainAnalysis((long)sample_frequency) == INIT_GAIN_ANALYSIS_OK;
}
FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__bool is_stereo, unsigned bps, unsigned samples)
{
/* using a small buffer improves data locality; we'd like it to fit easily in the dcache */
static flac_float_t lbuffer[2048], rbuffer[2048];
static const unsigned nbuffer = sizeof(lbuffer) / sizeof(lbuffer[0]);
FLAC__int32 block_peak = 0, s;
unsigned i, j;
FLAC__ASSERT(bps >= 4 && bps <= FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE);
FLAC__ASSERT(FLAC__MIN_BITS_PER_SAMPLE == 4);
/*
* We use abs() on a FLAC__int32 which is undefined for the most negative value.
* If the reference codec ever handles 32bps we will have to write a special
* case here.
*/
FLAC__ASSERT(FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE < 32);
if(bps == 16) {
if(is_stereo) {
j = 0;
while(samples > 0) {
const unsigned n = local_min(samples, nbuffer);
for(i = 0; i < n; i++, j++) {
s = input[0][j];
lbuffer[i] = (flac_float_t)s;
s = abs(s);
block_peak = local_max(block_peak, s);
s = input[1][j];
rbuffer[i] = (flac_float_t)s;
s = abs(s);
block_peak = local_max(block_peak, s);
}
samples -= n;
if(AnalyzeSamples(lbuffer, rbuffer, n, 2) != GAIN_ANALYSIS_OK)
return false;
}
}
else {
j = 0;
while(samples > 0) {
const unsigned n = local_min(samples, nbuffer);
for(i = 0; i < n; i++, j++) {
s = input[0][j];
lbuffer[i] = (flac_float_t)s;
s = abs(s);
block_peak = local_max(block_peak, s);
}
samples -= n;
if(AnalyzeSamples(lbuffer, 0, n, 1) != GAIN_ANALYSIS_OK)
return false;
}
}
}
else { /* bps must be < 32 according to above assertion */
const double scale = (
(bps > 16)?
(double)1. / (double)(1u << (bps - 16)) :
(double)(1u << (16 - bps))
);
if(is_stereo) {
j = 0;
while(samples > 0) {
const unsigned n = local_min(samples, nbuffer);
for(i = 0; i < n; i++, j++) {
s = input[0][j];
lbuffer[i] = (flac_float_t)(scale * (double)s);
s = abs(s);
block_peak = local_max(block_peak, s);
s = input[1][j];
rbuffer[i] = (flac_float_t)(scale * (double)s);
s = abs(s);
block_peak = local_max(block_peak, s);
}
samples -= n;
if(AnalyzeSamples(lbuffer, rbuffer, n, 2) != GAIN_ANALYSIS_OK)
return false;
}
}
else {
j = 0;
while(samples > 0) {
const unsigned n = local_min(samples, nbuffer);
for(i = 0; i < n; i++, j++) {
s = input[0][j];
lbuffer[i] = (flac_float_t)(scale * (double)s);
s = abs(s);
block_peak = local_max(block_peak, s);
}
samples -= n;
if(AnalyzeSamples(lbuffer, 0, n, 1) != GAIN_ANALYSIS_OK)
return false;
}
}
}
{
const double peak_scale = (double)(1u << (bps - 1));
double peak = (double)block_peak / peak_scale;
if(peak > title_peak_)
title_peak_ = peak;
if(peak > album_peak_)
album_peak_ = peak;
}
return true;
}
void grabbag__replaygain_get_album(float *gain, float *peak)
{
*gain = (float)GetAlbumGain();
*peak = (float)album_peak_;
album_peak_ = 0.0;
}
void grabbag__replaygain_get_title(float *gain, float *peak)
{
*gain = (float)GetTitleGain();
*peak = (float)title_peak_;
title_peak_ = 0.0;
}
typedef struct {
unsigned channels;
unsigned bits_per_sample;
unsigned sample_rate;
FLAC__bool error;
} DecoderInstance;
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
DecoderInstance *instance = (DecoderInstance*)client_data;
const unsigned bits_per_sample = frame->header.bits_per_sample;
const unsigned channels = frame->header.channels;
const unsigned sample_rate = frame->header.sample_rate;
const unsigned samples = frame->header.blocksize;
(void)decoder;
if(
!instance->error &&
(channels == 2 || channels == 1) &&
bits_per_sample == instance->bits_per_sample &&
channels == instance->channels &&
sample_rate == instance->sample_rate
) {
instance->error = !grabbag__replaygain_analyze(buffer, channels==2, bits_per_sample, samples);
}
else {
instance->error = true;
}
if(!instance->error)
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
else
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
DecoderInstance *instance = (DecoderInstance*)client_data;
(void)decoder;
if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
instance->bits_per_sample = metadata->data.stream_info.bits_per_sample;
instance->channels = metadata->data.stream_info.channels;
instance->sample_rate = metadata->data.stream_info.sample_rate;
if(instance->channels != 1 && instance->channels != 2) {
instance->error = true;
return;
}
if(!grabbag__replaygain_is_valid_sample_frequency(instance->sample_rate)) {
instance->error = true;
return;
}
}
}
static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
DecoderInstance *instance = (DecoderInstance*)client_data;
(void)decoder, (void)status;
instance->error = true;
}
const char *grabbag__replaygain_analyze_file(const char *filename, float *title_gain, float *title_peak)
{
DecoderInstance instance;
FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
if(0 == decoder)
return "memory allocation error";
instance.error = false;
/* It does these three by default but lets be explicit: */
FLAC__stream_decoder_set_md5_checking(decoder, false);
FLAC__stream_decoder_set_metadata_ignore_all(decoder);
FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &instance) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
FLAC__stream_decoder_delete(decoder);
return "initializing decoder";
}
if(!FLAC__stream_decoder_process_until_end_of_stream(decoder) || instance.error) {
FLAC__stream_decoder_delete(decoder);
return "decoding file";
}
FLAC__stream_decoder_delete(decoder);
grabbag__replaygain_get_title(title_gain, title_peak);
return 0;
}
const char *grabbag__replaygain_store_to_vorbiscomment(FLAC__StreamMetadata *block, float album_gain, float album_peak, float title_gain, float title_peak)
{
const char *error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block)))
return error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak)))
return error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_album(block, album_gain, album_peak)))
return error;
return 0;
}
const char *grabbag__replaygain_store_to_vorbiscomment_reference(FLAC__StreamMetadata *block)
{
FLAC__ASSERT(0 != block);
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
if(FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS) < 0)
return "memory allocation error";
if(!append_tag_(block, reference_format_, GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS, ReplayGainReferenceLoudness))
return "memory allocation error";
return 0;
}
const char *grabbag__replaygain_store_to_vorbiscomment_album(FLAC__StreamMetadata *block, float album_gain, float album_peak)
{
FLAC__ASSERT(0 != block);
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
if(
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN) < 0 ||
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK) < 0
)
return "memory allocation error";
if(
!append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN, album_gain) ||
!append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK, album_peak)
)
return "memory allocation error";
return 0;
}
const char *grabbag__replaygain_store_to_vorbiscomment_title(FLAC__StreamMetadata *block, float title_gain, float title_peak)
{
FLAC__ASSERT(0 != block);
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
if(
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN) < 0 ||
FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK) < 0
)
return "memory allocation error";
if(
!append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN, title_gain) ||
!append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK, title_peak)
)
return "memory allocation error";
return 0;
}
static const char *store_to_file_pre_(const char *filename, FLAC__Metadata_Chain **chain, FLAC__StreamMetadata **block)
{
FLAC__Metadata_Iterator *iterator;
const char *error;
FLAC__bool found_vc_block = false;
if(0 == (*chain = FLAC__metadata_chain_new()))
return "memory allocation error";
if(!FLAC__metadata_chain_read(*chain, filename)) {
error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(*chain)];
FLAC__metadata_chain_delete(*chain);
return error;
}
if(0 == (iterator = FLAC__metadata_iterator_new())) {
FLAC__metadata_chain_delete(*chain);
return "memory allocation error";
}
FLAC__metadata_iterator_init(iterator, *chain);
do {
*block = FLAC__metadata_iterator_get_block(iterator);
if((*block)->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
found_vc_block = true;
} while(!found_vc_block && FLAC__metadata_iterator_next(iterator));
if(!found_vc_block) {
/* create a new block */
*block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
if(0 == *block) {
FLAC__metadata_chain_delete(*chain);
FLAC__metadata_iterator_delete(iterator);
return "memory allocation error";
}
while(FLAC__metadata_iterator_next(iterator))
;
if(!FLAC__metadata_iterator_insert_block_after(iterator, *block)) {
error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(*chain)];
FLAC__metadata_chain_delete(*chain);
FLAC__metadata_iterator_delete(iterator);
return error;
}
/* iterator is left pointing to new block */
FLAC__ASSERT(FLAC__metadata_iterator_get_block(iterator) == *block);
}
FLAC__metadata_iterator_delete(iterator);
FLAC__ASSERT(0 != *block);
FLAC__ASSERT((*block)->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
return 0;
}
static const char *store_to_file_post_(const char *filename, FLAC__Metadata_Chain *chain, FLAC__bool preserve_modtime)
{
struct flac_stat_s stats;
const FLAC__bool have_stats = get_file_stats_(filename, &stats);
(void)grabbag__file_change_stats(filename, /*read_only=*/false);
FLAC__metadata_chain_sort_padding(chain);
if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, preserve_modtime)) {
const char *error;
error = FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(chain)];
FLAC__metadata_chain_delete(chain);
return error;
}
FLAC__metadata_chain_delete(chain);
if(have_stats)
set_file_stats_(filename, &stats);
return 0;
}
const char *grabbag__replaygain_store_to_file(const char *filename, float album_gain, float album_peak, float title_gain, float title_peak, FLAC__bool preserve_modtime)
{
FLAC__Metadata_Chain *chain;
FLAC__StreamMetadata *block = NULL;
const char *error;
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
return error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment(block, album_gain, album_peak, title_gain, title_peak))) {
FLAC__metadata_chain_delete(chain);
return error;
}
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
return error;
return 0;
}
const char *grabbag__replaygain_store_to_file_reference(const char *filename, FLAC__bool preserve_modtime)
{
FLAC__Metadata_Chain *chain;
FLAC__StreamMetadata *block = NULL;
const char *error;
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
return error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block))) {
FLAC__metadata_chain_delete(chain);
return error;
}
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
return error;
return 0;
}
const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime)
{
FLAC__Metadata_Chain *chain;
FLAC__StreamMetadata *block = NULL;
const char *error;
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
return error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_album(block, album_gain, album_peak))) {
FLAC__metadata_chain_delete(chain);
return error;
}
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
return error;
return 0;
}
const char *grabbag__replaygain_store_to_file_title(const char *filename, float title_gain, float title_peak, FLAC__bool preserve_modtime)
{
FLAC__Metadata_Chain *chain;
FLAC__StreamMetadata *block = NULL;
const char *error;
if(0 != (error = store_to_file_pre_(filename, &chain, &block)))
return error;
if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak))) {
FLAC__metadata_chain_delete(chain);
return error;
}
if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime)))
return error;
return 0;
}
static FLAC__bool parse_double_(const FLAC__StreamMetadata_VorbisComment_Entry *entry, double *val)
{
char s[32], *end;
const char *p, *q;
double v;
FLAC__ASSERT(0 != entry);
FLAC__ASSERT(0 != val);
p = (const char *)entry->entry;
q = strchr(p, '=');
if(0 == q)
return false;
q++;
safe_strncpy(s, q, local_min(sizeof(s), (size_t) (entry->length - (q-p))));
v = strtod(s, &end);
if(end == s)
return false;
*val = v;
return true;
}
FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak)
{
int reference_offset, gain_offset, peak_offset;
char *saved_locale;
FLAC__bool res = true;
FLAC__ASSERT(0 != block);
FLAC__ASSERT(0 != reference);
FLAC__ASSERT(0 != gain);
FLAC__ASSERT(0 != peak);
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
/* Default to current level until overridden by a detected tag; this
* will always be true until we change replaygain_analysis.c
*/
*reference = ReplayGainReferenceLoudness;
/*
* We need to save the old locale and switch to "C" because the locale
* influences the behaviour of strtod and we want it a certain way.
*/
saved_locale = strdup(setlocale(LC_ALL, 0));
if (0 == saved_locale)
return false;
setlocale(LC_ALL, "C");
if(0 <= (reference_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS)))
(void)parse_double_(block->data.vorbis_comment.comments + reference_offset, reference);
if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN : GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN))))
res = false;
if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK : GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK))))
res = false;
if(res && !parse_double_(block->data.vorbis_comment.comments + gain_offset, gain))
res = false;
if(res && !parse_double_(block->data.vorbis_comment.comments + peak_offset, peak))
res = false;
setlocale(LC_ALL, saved_locale);
free(saved_locale);
/* something failed; retry with strict */
if (!res && !strict)
res = grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak);
return res;
}
double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping)
{
double scale;
FLAC__ASSERT(peak >= 0.0);
gain += preamp;
scale = (float) pow(10.0, gain * 0.05);
if(prevent_clipping && peak > 0.0) {
const double max_scale = (float)(1.0 / peak);
if(scale > max_scale)
scale = max_scale;
}
return scale;
}

View File

@ -0,0 +1,106 @@
/* grabbag - Convenience lib for various routines common to several tools
* Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "share/grabbag.h"
#include "share/compat.h"
#include "FLAC/assert.h"
#include <stdlib.h> /* for atoi() */
#include <string.h>
FLAC__bool grabbag__seektable_convert_specification_to_template(const char *spec, FLAC__bool only_explicit_placeholders, FLAC__uint64 total_samples_to_encode, unsigned sample_rate, FLAC__StreamMetadata *seektable_template, FLAC__bool *spec_has_real_points)
{
unsigned i;
const char *pt;
FLAC__ASSERT(0 != spec);
FLAC__ASSERT(0 != seektable_template);
FLAC__ASSERT(seektable_template->type == FLAC__METADATA_TYPE_SEEKTABLE);
if(0 != spec_has_real_points)
*spec_has_real_points = false;
for(pt = spec, i = 0; pt && *pt; i++) {
const char *q = strchr(pt, ';');
FLAC__ASSERT(0 != q);
if(q > pt) {
if(0 == strncmp(pt, "X;", 2)) { /* -S X */
if(!FLAC__metadata_object_seektable_template_append_placeholders(seektable_template, 1))
return false;
}
else if(q[-1] == 'x') { /* -S #x */
if(total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */
if(0 != spec_has_real_points)
*spec_has_real_points = true;
if(!only_explicit_placeholders) {
const int n = (unsigned)atoi(pt);
if(n > 0)
if(!FLAC__metadata_object_seektable_template_append_spaced_points(seektable_template, (unsigned)n, total_samples_to_encode))
return false;
}
}
}
else if(q[-1] == 's') { /* -S #s */
if(total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */
FLAC__ASSERT(sample_rate > 0);
if(0 != spec_has_real_points)
*spec_has_real_points = true;
if(!only_explicit_placeholders) {
const double sec = atof(pt);
if(sec > 0.0) {
unsigned samples = (unsigned)(sec * (double)sample_rate);
/* Restrict seekpoints to two per second of audio. */
samples = samples < sample_rate / 2 ? sample_rate / 2 : samples;
if(samples > 0) {
/* +1 for the initial point at sample 0 */
if(!FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(seektable_template, samples, total_samples_to_encode))
return false;
}
}
}
}
}
else { /* -S # */
if(0 != spec_has_real_points)
*spec_has_real_points = true;
if(!only_explicit_placeholders) {
char *endptr;
const FLAC__int64 n = (FLAC__int64)strtoll(pt, &endptr, 10);
if(
(n > 0 || (endptr > pt && *endptr == ';')) && /* is a valid number (extra check needed for "0") */
(total_samples_to_encode == 0 || (FLAC__uint64)n < total_samples_to_encode) /* number is not >= the known total_samples_to_encode */
)
if(!FLAC__metadata_object_seektable_template_append_point(seektable_template, (FLAC__uint64)n))
return false;
}
}
}
pt = ++q;
}
if(!FLAC__metadata_object_seektable_template_sort(seektable_template, /*compact=*/true))
return false;
return true;
}

View File

@ -0,0 +1,101 @@
/* grabbag - Convenience lib for various routines common to several tools
* Copyright (C) 2013-2016 Xiph.org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include "share/compat.h"
/*
* FLAC needs to compile and work correctly on systems with a normal ISO C99
* snprintf as well as Microsoft Visual Studio which has an non-standards
* conformant snprint_s function.
*
* The important difference occurs when the resultant string (plus string
* terminator) would have been longer than the supplied size parameter. When
* this happens, ISO C's snprintf returns the length of resultant string, but
* does not over-write the end of the buffer. MS's snprintf_s in this case
* returns -1.
*
* The _MSC_VER code below attempts to modify the return code for vsnprintf_s
* to something that is more compatible with the behaviour of the ISO C version.
*/
int
flac_snprintf(char *str, size_t size, const char *fmt, ...)
{
va_list va;
int rc;
#if defined _MSC_VER
if (size == 0)
return 1024;
#endif
va_start (va, fmt);
#if defined _MSC_VER
rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
if (rc < 0)
rc = size - 1;
#elif defined __MINGW32__
rc = __mingw_vsnprintf (str, size, fmt, va);
#else
rc = vsnprintf (str, size, fmt, va);
#endif
va_end (va);
return rc;
}
int
flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
{
int rc;
#if defined _MSC_VER
if (size == 0)
return 1024;
rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
if (rc < 0)
rc = size - 1;
#elif defined __MINGW32__
rc = __mingw_vsnprintf (str, size, fmt, va);
#else
rc = vsnprintf (str, size, fmt, va);
#endif
return rc;
}

View File

@ -0,0 +1,15 @@
#
# GNU makefile
#
topdir = ../../..
LIB_NAME = libreplaygain_analysis
INCLUDES = -I$(topdir)/include
SRCS_C = \
replaygain_analysis.c
include $(topdir)/build/lib.mk
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,572 @@
/*
* ReplayGainAnalysis - analyzes input samples and give the recommended dB change
* Copyright (C) 2001 David Robinson and Glen Sawyer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* concept and filter values by David Robinson (David@Robinson.org)
* -- blame him if you think the idea is flawed
* original coding by Glen Sawyer (glensawyer@hotmail.com)
* -- blame him if you think this runs too slowly, or the coding is otherwise flawed
*
* lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ )
* -- credit him for all the _good_ programming ;)
*
* minor cosmetic tweaks to integrate with FLAC by Josh Coalson
*
*
* For an explanation of the concepts and the basic algorithms involved, go to:
* http://www.replaygain.org/
*/
/*
* Here's the deal. Call
*
* InitGainAnalysis ( long samplefreq );
*
* to initialize everything. Call
*
* AnalyzeSamples ( const flac_float_t* left_samples,
* const flac_float_t* right_samples,
* size_t num_samples,
* int num_channels );
*
* as many times as you want, with as many or as few samples as you want.
* If mono, pass the sample buffer in through left_samples, leave
* right_samples NULL, and make sure num_channels = 1.
*
* GetTitleGain()
*
* will return the recommended dB level change for all samples analyzed
* SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis().
*
* GetAlbumGain()
*
* will return the recommended dB level change for all samples analyzed
* since InitGainAnalysis() was called and finalized with GetTitleGain().
*
* Pseudo-code to process an album:
*
* flac_float_t l_samples [4096];
* flac_float_t r_samples [4096];
* size_t num_samples;
* unsigned int num_songs;
* unsigned int i;
*
* InitGainAnalysis ( 44100 );
* for ( i = 1; i <= num_songs; i++ ) {
* while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 )
* AnalyzeSamples ( left_samples, right_samples, num_samples, 2 );
* fprintf ("Recommended dB change for song %2d: %+6.2f dB\n", i, GetTitleGain() );
* }
* fprintf ("Recommended dB change for whole album: %+6.2f dB\n", GetAlbumGain() );
*/
/*
* So here's the main source of potential code confusion:
*
* The filters applied to the incoming samples are IIR filters,
* meaning they rely on up to <filter order> number of previous samples
* AND up to <filter order> number of previous filtered samples.
*
* I set up the AnalyzeSamples routine to minimize memory usage and interface
* complexity. The speed isn't compromised too much (I don't think), but the
* internal complexity is higher than it should be for such a relatively
* simple routine.
*
* Optimization/clarity suggestions are welcome.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "share/alloc.h"
#include "share/compat.h"
#include "share/replaygain_analysis.h"
flac_float_t ReplayGainReferenceLoudness = 89.0; /* in dB SPL */
#define YULE_ORDER 10
#define BUTTER_ORDER 2
#define RMS_PERCENTILE 0.95 /* percentile which is louder than the proposed level */
#define RMS_WINDOW_TIME 50 /* Time slice size [ms] */
#define STEPS_per_dB 100. /* Table entries per dB */
#define MAX_dB 120. /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */
#define MAX_ORDER (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER)
#define PINK_REF 64.82 /* 298640883795 */ /* calibration value */
static flac_float_t linprebuf [MAX_ORDER * 2];
static flac_float_t* linpre; /* left input samples, with pre-buffer */
static flac_float_t* lstepbuf;
static flac_float_t* lstep; /* left "first step" (i.e. post first filter) samples */
static flac_float_t* loutbuf;
static flac_float_t* lout; /* left "out" (i.e. post second filter) samples */
static flac_float_t rinprebuf [MAX_ORDER * 2];
static flac_float_t* rinpre; /* right input samples ... */
static flac_float_t* rstepbuf;
static flac_float_t* rstep;
static flac_float_t* routbuf;
static flac_float_t* rout;
static unsigned int sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */
static unsigned long totsamp;
static double lsum;
static double rsum;
#if 0
static uint32_t A [(size_t)(STEPS_per_dB * MAX_dB)];
static uint32_t B [(size_t)(STEPS_per_dB * MAX_dB)];
#else
/* [JEC] Solaris Forte compiler doesn't like float calc in array indices */
static uint32_t A [120 * 100];
static uint32_t B [120 * 100];
#endif
#ifdef _MSC_VER
#pragma warning ( disable : 4305 )
#endif
struct ReplayGainFilter {
long rate;
unsigned downsample;
flac_float_t BYule[YULE_ORDER+1];
flac_float_t AYule[YULE_ORDER+1];
flac_float_t BButter[BUTTER_ORDER+1];
flac_float_t AButter[BUTTER_ORDER+1];
};
static struct ReplayGainFilter *replaygainfilter;
static const struct ReplayGainFilter ReplayGainFilters[] = {
{
48000, 0, /* ORIGINAL */
{ 0.03857599435200, -0.02160367184185, -0.00123395316851, -0.00009291677959, -0.01655260341619, 0.02161526843274, -0.02074045215285, 0.00594298065125, 0.00306428023191, 0.00012025322027, 0.00288463683916 },
{ 1.00000000000000, -3.84664617118067, 7.81501653005538, -11.34170355132042, 13.05504219327545, -12.28759895145294, 9.48293806319790, -5.87257861775999, 2.75465861874613, -0.86984376593551, 0.13919314567432 },
{ 0.98621192462708, -1.97242384925416, 0.98621192462708 },
{ 1.00000000000000, -1.97223372919527, 0.97261396931306 },
},
{
44100, 0, /* ORIGINAL */
{ 0.05418656406430, -0.02911007808948, -0.00848709379851, -0.00851165645469, -0.00834990904936, 0.02245293253339, -0.02596338512915, 0.01624864962975, -0.00240879051584, 0.00674613682247, -0.00187763777362 },
{ 1.00000000000000, -3.47845948550071, 6.36317777566148, -8.54751527471874, 9.47693607801280, -8.81498681370155, 6.85401540936998, -4.39470996079559, 2.19611684890774, -0.75104302451432, 0.13149317958808 },
{ 0.98500175787242, -1.97000351574484, 0.98500175787242 },
{ 1.00000000000000, -1.96977855582618, 0.97022847566350 },
},
{
37800, 0,
{ 0.10296717174470, -0.04877975583256, -0.02878009075237, -0.03519509188311, 0.02888717172493, -0.00609872684844, 0.00209851217112, 0.00911704668543, 0.01154404718589, -0.00630293688700, 0.00107527155228 },
{ 1.00000000000000, -2.64848054923531, 3.58406058405771, -3.83794914179161, 3.90142345804575, -3.50179818637243, 2.67085284083076, -1.82581142372418, 1.09530368139801, -0.47689017820395, 0.11171431535905 },
{ 0.98252400815195, -1.96504801630391, 0.98252400815195 },
{ 1.00000000000000, -1.96474258269041, 0.96535344991740 },
},
{
36000, 0,
{ 0.11572297028613, -0.04120916051252, -0.04977731768022, -0.01047308680426, 0.00750863219157, 0.00055507694408, 0.00140344192886, 0.01286095246036, 0.00998223033885, -0.00725013810661, 0.00326503346879 },
{ 1.00000000000000, -2.43606802820871, 3.01907406973844, -2.90372016038192, 2.67947188094303, -2.17606479220391, 1.44912956803015, -0.87785765549050, 0.53592202672557, -0.26469344817509, 0.07495878059717 },
{ 0.98165826840326, -1.96331653680652, 0.98165826840326 },
{ 1.00000000000000, -1.96298008938934, 0.96365298422371 },
},
{
32000, 0, /* ORIGINAL */
{ 0.15457299681924, -0.09331049056315, -0.06247880153653, 0.02163541888798, -0.05588393329856, 0.04781476674921, 0.00222312597743, 0.03174092540049, -0.01390589421898, 0.00651420667831, -0.00881362733839 },
{ 1.00000000000000, -2.37898834973084, 2.84868151156327, -2.64577170229825, 2.23697657451713, -1.67148153367602, 1.00595954808547, -0.45953458054983, 0.16378164858596, -0.05032077717131, 0.02347897407020 },
{ 0.97938932735214, -1.95877865470428, 0.97938932735214 },
{ 1.00000000000000, -1.95835380975398, 0.95920349965459 },
},
{
28000, 0,
{ 0.23882392323383, -0.22007791534089, -0.06014581950332, 0.05004458058021, -0.03293111254977, 0.02348678189717, 0.04290549799671, -0.00938141862174, 0.00015095146303, -0.00712601540885, -0.00626520210162 },
{ 1.00000000000000, -2.06894080899139, 1.76944699577212, -0.81404732584187, 0.25418286850232, -0.30340791669762, 0.35616884070937, -0.14967310591258, -0.07024154183279, 0.11078404345174, -0.03551838002425 },
{ 0.97647981663949, -1.95295963327897, 0.97647981663949 },
{ 1.00000000000000, -1.95240635772520, 0.95351290883275 },
},
{
24000, 0, /* ORIGINAL */
{ 0.30296907319327, -0.22613988682123, -0.08587323730772, 0.03282930172664, -0.00915702933434, -0.02364141202522, -0.00584456039913, 0.06276101321749, -0.00000828086748, 0.00205861885564, -0.02950134983287 },
{ 1.00000000000000, -1.61273165137247, 1.07977492259970, -0.25656257754070, -0.16276719120440, -0.22638893773906, 0.39120800788284, -0.22138138954925, 0.04500235387352, 0.02005851806501, 0.00302439095741 },
{ 0.97531843204928, -1.95063686409857, 0.97531843204928 },
{ 1.00000000000000, -1.95002759149878, 0.95124613669835 },
},
{
22050, 0, /* ORIGINAL */
{ 0.33642304856132, -0.25572241425570, -0.11828570177555, 0.11921148675203, -0.07834489609479, -0.00469977914380, -0.00589500224440, 0.05724228140351, 0.00832043980773, -0.01635381384540, -0.01760176568150 },
{ 1.00000000000000, -1.49858979367799, 0.87350271418188, 0.12205022308084, -0.80774944671438, 0.47854794562326, -0.12453458140019, -0.04067510197014, 0.08333755284107, -0.04237348025746, 0.02977207319925 },
{ 0.97316523498161, -1.94633046996323, 0.97316523498161 },
{ 1.00000000000000, -1.94561023566527, 0.94705070426118 },
},
{
18900, 0,
{ 0.38412657295385, -0.44533729608120, 0.20426638066221, -0.28031676047946, 0.31484202614802, -0.26078311203207, 0.12925201224848, -0.01141164696062, 0.03036522115769, -0.03776339305406, 0.00692036603586 },
{ 1.00000000000000, -1.74403915585708, 1.96686095832499, -2.10081452941881, 1.90753918182846, -1.83814263754422, 1.36971352214969, -0.77883609116398, 0.39266422457649, -0.12529383592986, 0.05424760697665 },
{ 0.96535326815829, -1.93070653631658, 0.96535326815829 },
{ 1.00000000000000, -1.92950577983524, 0.93190729279793 },
},
{
16000, 0, /* ORIGINAL */
{ 0.44915256608450, -0.14351757464547, -0.22784394429749, -0.01419140100551, 0.04078262797139, -0.12398163381748, 0.04097565135648, 0.10478503600251, -0.01863887810927, -0.03193428438915, 0.00541907748707 },
{ 1.00000000000000, -0.62820619233671, 0.29661783706366, -0.37256372942400, 0.00213767857124, -0.42029820170918, 0.22199650564824, 0.00613424350682, 0.06747620744683, 0.05784820375801, 0.03222754072173 },
{ 0.96454515552826, -1.92909031105652, 0.96454515552826 },
{ 1.00000000000000, -1.92783286977036, 0.93034775234268 },
},
{
12000, 0, /* ORIGINAL */
{ 0.56619470757641, -0.75464456939302, 0.16242137742230, 0.16744243493672, -0.18901604199609, 0.30931782841830, -0.27562961986224, 0.00647310677246, 0.08647503780351, -0.03788984554840, -0.00588215443421 },
{ 1.00000000000000, -1.04800335126349, 0.29156311971249, -0.26806001042947, 0.00819999645858, 0.45054734505008, -0.33032403314006, 0.06739368333110, -0.04784254229033, 0.01639907836189, 0.01807364323573 },
{ 0.96009142950541, -1.92018285901082, 0.96009142950541 },
{ 1.00000000000000, -1.91858953033784, 0.92177618768381 },
},
{
11025, 0, /* ORIGINAL */
{ 0.58100494960553, -0.53174909058578, -0.14289799034253, 0.17520704835522, 0.02377945217615, 0.15558449135573, -0.25344790059353, 0.01628462406333, 0.06920467763959, -0.03721611395801, -0.00749618797172 },
{ 1.00000000000000, -0.51035327095184, -0.31863563325245, -0.20256413484477, 0.14728154134330, 0.38952639978999, -0.23313271880868, -0.05246019024463, -0.02505961724053, 0.02442357316099, 0.01818801111503 },
{ 0.95856916599601, -1.91713833199203, 0.95856916599601 },
{ 1.00000000000000, -1.91542108074780, 0.91885558323625 },
},
{
8000, 0, /* ORIGINAL */
{ 0.53648789255105, -0.42163034350696, -0.00275953611929, 0.04267842219415, -0.10214864179676, 0.14590772289388, -0.02459864859345, -0.11202315195388, -0.04060034127000, 0.04788665548180, -0.02217936801134 },
{ 1.00000000000000, -0.25049871956020, -0.43193942311114, -0.03424681017675, -0.04678328784242, 0.26408300200955, 0.15113130533216, -0.17556493366449, -0.18823009262115, 0.05477720428674, 0.04704409688120 },
{ 0.94597685600279, -1.89195371200558, 0.94597685600279 },
{ 1.00000000000000, -1.88903307939452, 0.89487434461664 },
},
};
#ifdef _MSC_VER
#pragma warning ( default : 4305 )
#endif
/* When calling this procedure, make sure that ip[-order] and op[-order] point to real data! */
static void
filter ( const flac_float_t* input, flac_float_t* output, size_t nSamples, const flac_float_t* a, const flac_float_t* b, size_t order, unsigned downsample )
{
double y;
size_t i;
size_t k;
const flac_float_t* input_head = input;
const flac_float_t* input_tail;
flac_float_t* output_head = output;
flac_float_t* output_tail;
for ( i = 0; i < nSamples; i++, input_head += downsample, ++output_head ) {
input_tail = input_head;
output_tail = output_head;
y = *input_head * b[0];
for ( k = 1; k <= order; k++ ) {
input_tail -= downsample;
--output_tail;
y += *input_tail * b[k] - *output_tail * a[k];
}
output[i] = (flac_float_t)y;
}
}
/* returns a INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if not */
static struct ReplayGainFilter*
CreateGainFilter ( long samplefreq )
{
unsigned i;
long maxrate = 0;
unsigned downsample = 1;
struct ReplayGainFilter* gainfilter = malloc(sizeof(*gainfilter));
if ( !gainfilter )
return 0;
while (1) {
for ( i = 0; i < sizeof(ReplayGainFilters)/sizeof(ReplayGainFilters[0]); ++i ) {
if (maxrate < ReplayGainFilters[i].rate)
maxrate = ReplayGainFilters[i].rate;
if ( ReplayGainFilters[i].rate == samplefreq ) {
*gainfilter = ReplayGainFilters[i];
gainfilter->downsample = downsample;
return gainfilter;
}
}
if (samplefreq < maxrate)
break;
while (samplefreq > maxrate) {
downsample *= 2;
samplefreq /= 2;
}
}
free(gainfilter);
return 0;
}
static void*
ReallocateWindowBuffer(unsigned window_size, flac_float_t **window_buffer)
{
*window_buffer = safe_realloc_(*window_buffer, sizeof(**window_buffer) * (window_size + MAX_ORDER));
return *window_buffer;
}
static int
ResetSampleFrequency ( long samplefreq ) {
int i;
free(replaygainfilter);
replaygainfilter = CreateGainFilter( samplefreq );
if ( ! replaygainfilter)
return INIT_GAIN_ANALYSIS_ERROR;
sampleWindow =
(replaygainfilter->rate * RMS_WINDOW_TIME + 1000-1) / 1000;
if ( ! ReallocateWindowBuffer(sampleWindow, &lstepbuf) ||
! ReallocateWindowBuffer(sampleWindow, &rstepbuf) ||
! ReallocateWindowBuffer(sampleWindow, &loutbuf) ||
! ReallocateWindowBuffer(sampleWindow, &routbuf) ) {
return INIT_GAIN_ANALYSIS_ERROR;
}
/* zero out initial values */
for ( i = 0; i < MAX_ORDER; i++ )
linprebuf[i] = lstepbuf[i] = loutbuf[i] = rinprebuf[i] = rstepbuf[i] = routbuf[i] = 0.;
lsum = 0.;
rsum = 0.;
totsamp = 0;
memset ( A, 0, sizeof(A) );
return INIT_GAIN_ANALYSIS_OK;
}
int
ValidGainFrequency ( long samplefreq )
{
struct ReplayGainFilter* gainfilter = CreateGainFilter( samplefreq );
free(gainfilter);
return gainfilter != 0;
}
int
InitGainAnalysis ( long samplefreq )
{
if (ResetSampleFrequency(samplefreq) != INIT_GAIN_ANALYSIS_OK) {
return INIT_GAIN_ANALYSIS_ERROR;
}
linpre = linprebuf + MAX_ORDER;
rinpre = rinprebuf + MAX_ORDER;
lstep = lstepbuf + MAX_ORDER;
rstep = rstepbuf + MAX_ORDER;
lout = loutbuf + MAX_ORDER;
rout = routbuf + MAX_ORDER;
memset ( B, 0, sizeof(B) );
return INIT_GAIN_ANALYSIS_OK;
}
/* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */
int
AnalyzeSamples ( const flac_float_t* left_samples, const flac_float_t* right_samples, size_t num_samples, int num_channels )
{
unsigned downsample = replaygainfilter->downsample;
const flac_float_t* curleft;
const flac_float_t* curright;
long prebufsamples;
long batchsamples;
long cursamples;
long cursamplepos;
int i;
num_samples /= downsample;
if ( num_samples == 0 )
return GAIN_ANALYSIS_OK;
cursamplepos = 0;
batchsamples = num_samples;
switch ( num_channels) {
case 1: right_samples = left_samples;
case 2: break;
default: return GAIN_ANALYSIS_ERROR;
}
prebufsamples = MAX_ORDER;
if ((size_t) prebufsamples > num_samples)
prebufsamples = num_samples;
for ( i = 0; i < prebufsamples; ++i ) {
linprebuf[i+MAX_ORDER] = left_samples [i * downsample];
rinprebuf[i+MAX_ORDER] = right_samples[i * downsample];
}
while ( batchsamples > 0 ) {
cursamples = batchsamples > (long)(sampleWindow-totsamp) ? (long)(sampleWindow - totsamp) : batchsamples;
if ( cursamplepos < MAX_ORDER ) {
downsample = 1;
curleft = linpre+cursamplepos;
curright = rinpre+cursamplepos;
if (cursamples > MAX_ORDER - cursamplepos )
cursamples = MAX_ORDER - cursamplepos;
}
else {
downsample = replaygainfilter->downsample;
curleft = left_samples + cursamplepos * downsample;
curright = right_samples + cursamplepos * downsample;
}
filter ( curleft , lstep + totsamp, cursamples, replaygainfilter->AYule, replaygainfilter->BYule, YULE_ORDER, downsample );
filter ( curright, rstep + totsamp, cursamples, replaygainfilter->AYule, replaygainfilter->BYule, YULE_ORDER, downsample );
filter ( lstep + totsamp, lout + totsamp, cursamples, replaygainfilter->AButter, replaygainfilter->BButter, BUTTER_ORDER, 1 );
filter ( rstep + totsamp, rout + totsamp, cursamples, replaygainfilter->AButter, replaygainfilter->BButter, BUTTER_ORDER, 1 );
for ( i = 0; i < cursamples; i++ ) { /* Get the squared values */
lsum += lout [totsamp+i] * lout [totsamp+i];
rsum += rout [totsamp+i] * rout [totsamp+i];
}
batchsamples -= cursamples;
cursamplepos += cursamples;
totsamp += cursamples;
if ( totsamp == sampleWindow ) { /* Get the Root Mean Square (RMS) for this set of samples */
double val = STEPS_per_dB * 10. * log10 ( (lsum+rsum) / totsamp * 0.5 + 1.e-37 );
int ival = (int) val;
if ( ival < 0 ) ival = 0;
if ( ival >= (int)(sizeof(A)/sizeof(*A)) ) ival = (int)(sizeof(A)/sizeof(*A)) - 1;
A [ival]++;
lsum = rsum = 0.;
memmove ( loutbuf , loutbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) );
memmove ( routbuf , routbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) );
memmove ( lstepbuf, lstepbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) );
memmove ( rstepbuf, rstepbuf + totsamp, MAX_ORDER * sizeof(flac_float_t) );
totsamp = 0;
}
if ( totsamp > sampleWindow ) /* somehow I really screwed up: Error in programming! Contact author about totsamp > sampleWindow */
return GAIN_ANALYSIS_ERROR;
}
if ( num_samples < MAX_ORDER ) {
memmove ( linprebuf, linprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(flac_float_t) );
memmove ( rinprebuf, rinprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(flac_float_t) );
memcpy ( linprebuf + MAX_ORDER - num_samples, left_samples, num_samples * sizeof(flac_float_t) );
memcpy ( rinprebuf + MAX_ORDER - num_samples, right_samples, num_samples * sizeof(flac_float_t) );
}
else {
downsample = replaygainfilter->downsample;
left_samples += (num_samples - MAX_ORDER) * downsample;
right_samples += (num_samples - MAX_ORDER) * downsample;
for ( i = 0; i < MAX_ORDER; ++i ) {
linprebuf[i] = left_samples [i * downsample];
rinprebuf[i] = right_samples[i * downsample];
}
}
return GAIN_ANALYSIS_OK;
}
static flac_float_t
analyzeResult ( uint32_t* Array, size_t len )
{
uint32_t elems;
int32_t upper;
size_t i;
elems = 0;
for ( i = 0; i < len; i++ )
elems += Array[i];
if ( elems == 0 )
return GAIN_NOT_ENOUGH_SAMPLES;
/* workaround for GCC bug #61423: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61423 */
#if 0
upper = (int32_t) ceil (elems * (1. - RMS_PERCENTILE));
#else
upper = (int32_t) (elems / 20 + ((elems % 20) ? 1 : 0));
#endif
for ( i = len; i-- > 0; ) {
if ( (upper -= Array[i]) <= 0 )
break;
}
return (flac_float_t) ((flac_float_t)PINK_REF - (flac_float_t)i / (flac_float_t)STEPS_per_dB);
}
flac_float_t
GetTitleGain ( void )
{
flac_float_t retval;
unsigned int i;
retval = analyzeResult ( A, sizeof(A)/sizeof(*A) );
for ( i = 0; i < sizeof(A)/sizeof(*A); i++ ) {
B[i] += A[i];
A[i] = 0;
}
for ( i = 0; i < MAX_ORDER; i++ )
linprebuf[i] = lstepbuf[i] = loutbuf[i] = rinprebuf[i] = rstepbuf[i] = routbuf[i] = 0.f;
totsamp = 0;
lsum = rsum = 0.;
return retval;
}
flac_float_t
GetAlbumGain ( void )
{
return analyzeResult ( B, sizeof(B)/sizeof(*B) );
}
/* end of replaygain_analysis.c */

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="replaygain_analysis_static"
ProjectGUID="{4cefbc89-c215-11db-8314-0800200c9a66}"
RootNamespace="replaygain_analysis_static"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Public Header Files"
>
<File
RelativePath="..\..\..\include\share\replaygain_analysis.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\replaygain_analysis.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4cefbc89-c215-11db-8314-0800200c9a66}</ProjectGuid>
<RootNamespace>replaygain_analysis_static</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\replaygain_analysis.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="replaygain_analysis.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Public Header Files">
<UniqueIdentifier>{9e16659d-14e5-4477-be88-76193fff5d31}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\replaygain_analysis.h">
<Filter>Public Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="replaygain_analysis.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
#
# GNU makefile
#
topdir = ../../..
LIB_NAME = libreplaygain_synthesis
INCLUDES = -I./include -I$(topdir)/include
SRCS_C = \
replaygain_synthesis.c
include $(topdir)/build/lib.mk
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,423 @@
/* replaygain_synthesis - Routines for applying ReplayGain to a signal
* Copyright (C) 2002-2009 Josh Coalson
* Copyright (C) 2011-2016 Xiph.Org Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is an aggregation of pieces of code from John Edwards' WaveGain
* program. Mostly cosmetic changes were made; otherwise, the dithering
* code is almost untouched and the gain processing was converted from
* processing a whole file to processing chunks of samples.
*
* The original copyright notices for WaveGain's dither.c and wavegain.c
* appear below:
*/
/*
* (c) 2002 John Edwards
* mostly lifted from work by Frank Klemm
* random functions for dithering.
*/
/*
* Copyright (C) 2002 John Edwards
* Additional code by Magnus Holmgren and Gian-Carlo Pascutto
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h> /* for memset() */
#include <math.h>
#include "share/replaygain_synthesis.h"
#include "FLAC/assert.h"
#define FLAC__I64L(x) x##LL
/*
* the following is based on parts of dither.c
*/
/*
* This is a simple random number generator with good quality for audio purposes.
* It consists of two polycounters with opposite rotation direction and different
* periods. The periods are coprime, so the total period is the product of both.
*
* -------------------------------------------------------------------------------------------------
* +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
* | -------------------------------------------------------------------------------------------------
* | | | | | | |
* | +--+--+--+-XOR-+--------+
* | |
* +--------------------------------------------------------------------------------------+
*
* -------------------------------------------------------------------------------------------------
* |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
* ------------------------------------------------------------------------------------------------- |
* | | | | |
* +--+----XOR----+--+ |
* | |
* +----------------------------------------------------------------------------------------+
*
*
* The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
* which gives a period of 18.410.713.077.675.721.215. The result is the
* XORed values of both generators.
*/
static unsigned int random_int_(void)
{
static const unsigned char parity_[256] = {
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
};
static unsigned int r1_ = 1;
static unsigned int r2_ = 1;
unsigned int t1, t2, t3, t4;
/* Parity calculation is done via table lookup, this is also available
* on CPUs without parity, can be implemented in C and avoid unpredictable
* jumps and slow rotate through the carry flag operations.
*/
t3 = t1 = r1_; t4 = t2 = r2_;
t1 &= 0xF5; t2 >>= 25;
t1 = parity_[t1]; t2 &= 0x63;
t1 <<= 31; t2 = parity_[t2];
return (r1_ = (t3 >> 1) | t1 ) ^ (r2_ = (t4 + t4) | t2 );
}
/* gives a equal distributed random number */
/* between -2^31*mult and +2^31*mult */
static double random_equi_(double mult)
{
return mult * (int) random_int_();
}
/* gives a triangular distributed random number */
/* between -2^32*mult and +2^32*mult */
static double random_triangular_(double mult)
{
return mult * ( (double) (int) random_int_() + (double) (int) random_int_() );
}
static const float F44_0 [16 + 32] = {
(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0
};
static const float F44_1 [16 + 32] = { /* SNR(w) = 4.843163 dB, SNR = -3.192134 dB */
(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
};
static const float F44_2 [16 + 32] = { /* SNR(w) = 10.060213 dB, SNR = -12.766730 dB */
(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
};
static const float F44_3 [16 + 32] = { /* SNR(w) = 15.382598 dB, SNR = -29.402334 dB */
(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,
(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,
(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099
};
static double scalar16_(const float* x, const float* y)
{
return
x[ 0]*y[ 0] + x[ 1]*y[ 1] + x[ 2]*y[ 2] + x[ 3]*y[ 3] +
x[ 4]*y[ 4] + x[ 5]*y[ 5] + x[ 6]*y[ 6] + x[ 7]*y[ 7] +
x[ 8]*y[ 8] + x[ 9]*y[ 9] + x[10]*y[10] + x[11]*y[11] +
x[12]*y[12] + x[13]*y[13] + x[14]*y[14] + x[15]*y[15];
}
void FLAC__replaygain_synthesis__init_dither_context(DitherContext *d, int bits, int shapingtype)
{
static unsigned char default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67, 0, 0 };
static const float* F [] = { F44_0, F44_1, F44_2, F44_3 };
int indx;
if (shapingtype < 0) shapingtype = 0;
if (shapingtype > 3) shapingtype = 3;
d->ShapingType = (NoiseShaping)shapingtype;
indx = bits - 11 - shapingtype;
if (indx < 0) indx = 0;
if (indx > 9) indx = 9;
memset ( d->ErrorHistory , 0, sizeof (d->ErrorHistory ) );
memset ( d->DitherHistory, 0, sizeof (d->DitherHistory) );
d->FilterCoeff = F [shapingtype];
d->Mask = ((FLAC__uint64)-1) << (32 - bits);
d->Add = 0.5 * ((1L << (32 - bits)) - 1);
d->Dither = 0.01f*default_dither[indx] / (((FLAC__int64)1) << bits);
d->LastHistoryIndex = 0;
}
/*
* the following is based on parts of wavegain.c
*/
static FLAC__int64 dither_output_(DitherContext *d, FLAC__bool do_dithering, int shapingtype, int i, double Sum, int k)
{
union {
double d;
FLAC__int64 i;
} doubletmp;
double Sum2;
FLAC__int64 val;
#define ROUND64(x) ( doubletmp.d = (x) + d->Add + (FLAC__int64)FLAC__I64L(0x001FFFFD80000000), doubletmp.i - (FLAC__int64)FLAC__I64L(0x433FFFFD80000000) )
if(do_dithering) {
if(shapingtype == 0) {
double tmp = random_equi_(d->Dither);
Sum2 = tmp - d->LastRandomNumber [k];
d->LastRandomNumber [k] = (int)tmp;
Sum2 = Sum += Sum2;
val = ROUND64(Sum2) & d->Mask;
}
else {
Sum2 = random_triangular_(d->Dither) - scalar16_(d->DitherHistory[k], d->FilterCoeff + i);
Sum += d->DitherHistory [k] [(-1-i)&15] = (float)Sum2;
Sum2 = Sum + scalar16_(d->ErrorHistory [k], d->FilterCoeff + i);
val = ROUND64(Sum2) & d->Mask;
d->ErrorHistory [k] [(-1-i)&15] = (float)(Sum - val);
}
return val;
}
else
return ROUND64(Sum);
#undef ROUND64
}
#if 0
float peak = 0.f,
new_peak,
factor_clip
double scale,
dB;
...
peak is in the range -32768.0 .. 32767.0
/* calculate factors for ReplayGain and ClippingPrevention */
*track_gain = GetTitleGain() + settings->man_gain;
scale = (float) pow(10., *track_gain * 0.05);
if(settings->clip_prev) {
factor_clip = (float) (32767./( peak + 1));
if(scale < factor_clip)
factor_clip = 1.f;
else
factor_clip /= scale;
scale *= factor_clip;
}
new_peak = (float) peak * scale;
dB = 20. * log10(scale);
*track_gain = (float) dB;
const double scale = pow(10., (double)gain * 0.05);
#endif
size_t FLAC__replaygain_synthesis__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, FLAC__bool unsigned_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const double scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context)
{
static const FLAC__int64 hard_clip_factors_[33] = {
0, /* 0 bits-per-sample (not supported) */
0, /* 1 bits-per-sample (not supported) */
0, /* 2 bits-per-sample (not supported) */
0, /* 3 bits-per-sample (not supported) */
-8, /* 4 bits-per-sample */
-16, /* 5 bits-per-sample */
-32, /* 6 bits-per-sample */
-64, /* 7 bits-per-sample */
-128, /* 8 bits-per-sample */
-256, /* 9 bits-per-sample */
-512, /* 10 bits-per-sample */
-1024, /* 11 bits-per-sample */
-2048, /* 12 bits-per-sample */
-4096, /* 13 bits-per-sample */
-8192, /* 14 bits-per-sample */
-16384, /* 15 bits-per-sample */
-32768, /* 16 bits-per-sample */
-65536, /* 17 bits-per-sample */
-131072, /* 18 bits-per-sample */
-262144, /* 19 bits-per-sample */
-524288, /* 20 bits-per-sample */
-1048576, /* 21 bits-per-sample */
-2097152, /* 22 bits-per-sample */
-4194304, /* 23 bits-per-sample */
-8388608, /* 24 bits-per-sample */
-16777216, /* 25 bits-per-sample */
-33554432, /* 26 bits-per-sample */
-67108864, /* 27 bits-per-sample */
-134217728, /* 28 bits-per-sample */
-268435456, /* 29 bits-per-sample */
-536870912, /* 30 bits-per-sample */
-1073741824, /* 31 bits-per-sample */
(FLAC__int64)(-1073741824) * 2 /* 32 bits-per-sample */
};
const FLAC__int32 conv_shift = 32 - target_bps;
const FLAC__int64 hard_clip_factor = hard_clip_factors_[target_bps];
/*
* The integer input coming in has a varying range based on the
* source_bps. We want to normalize it to [-1.0, 1.0) so instead
* of doing two multiplies on each sample, we just multiple
* 'scale' by 1/(2^(source_bps-1))
*/
const double multi_scale = scale / (double)(1u << (source_bps-1));
FLAC__byte * const start = data_out;
unsigned i, channel;
const FLAC__int32 *input_;
double sample;
const unsigned bytes_per_sample = target_bps / 8;
const unsigned last_history_index = dither_context->LastHistoryIndex;
NoiseShaping noise_shaping = dither_context->ShapingType;
FLAC__int64 val64;
FLAC__int32 val32;
FLAC__int32 uval32;
const FLAC__uint32 twiggle = 1u << (target_bps - 1);
FLAC__ASSERT(channels > 0 && channels <= FLAC_SHARE__MAX_SUPPORTED_CHANNELS);
FLAC__ASSERT(source_bps >= 4);
FLAC__ASSERT(target_bps >= 4);
FLAC__ASSERT(source_bps <= 32);
FLAC__ASSERT(target_bps < 32);
FLAC__ASSERT((target_bps & 7) == 0);
for(channel = 0; channel < channels; channel++) {
const unsigned incr = bytes_per_sample * channels;
data_out = start + bytes_per_sample * channel;
input_ = input[channel];
for(i = 0; i < wide_samples; i++, data_out += incr) {
sample = (double)input_[i] * multi_scale;
if(hard_limit) {
/* hard 6dB limiting */
if(sample < -0.5)
sample = tanh((sample + 0.5) / (1-0.5)) * (1-0.5) - 0.5;
else if(sample > 0.5)
sample = tanh((sample - 0.5) / (1-0.5)) * (1-0.5) + 0.5;
}
sample *= 2147483647.;
val64 = dither_output_(dither_context, do_dithering, noise_shaping, (i + last_history_index) % 32, sample, channel) >> conv_shift;
val32 = (FLAC__int32)val64;
if(val64 >= -hard_clip_factor)
val32 = (FLAC__int32)(-(hard_clip_factor+1));
else if(val64 < hard_clip_factor)
val32 = (FLAC__int32)hard_clip_factor;
uval32 = (FLAC__uint32)val32;
if (unsigned_data_out)
uval32 ^= twiggle;
if (little_endian_data_out) {
switch(target_bps) {
case 24:
data_out[2] = (FLAC__byte)(uval32 >> 16);
/* fall through */
case 16:
data_out[1] = (FLAC__byte)(uval32 >> 8);
/* fall through */
case 8:
data_out[0] = (FLAC__byte)uval32;
break;
}
}
else {
switch(target_bps) {
case 24:
data_out[0] = (FLAC__byte)(uval32 >> 16);
data_out[1] = (FLAC__byte)(uval32 >> 8);
data_out[2] = (FLAC__byte)uval32;
break;
case 16:
data_out[0] = (FLAC__byte)(uval32 >> 8);
data_out[1] = (FLAC__byte)uval32;
break;
case 8:
data_out[0] = (FLAC__byte)uval32;
break;
}
}
}
}
dither_context->LastHistoryIndex = (last_history_index + wide_samples) % 32;
return wide_samples * channels * (target_bps/8);
}

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="replaygain_synthesis_static"
ProjectGUID="{4cefbc8a-c215-11db-8314-0800200c9a66}"
RootNamespace="replaygain_synthesis_static"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Public Header Files"
>
<File
RelativePath="..\..\..\include\share\replaygain_synthesis.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\replaygain_synthesis.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4cefbc8a-c215-11db-8314-0800200c9a66}</ProjectGuid>
<RootNamespace>replaygain_synthesis_static</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\replaygain_synthesis.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="replaygain_synthesis.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Public Header Files">
<UniqueIdentifier>{47ae72f8-630b-4044-b8ce-f4d560d70f4f}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\replaygain_synthesis.h">
<Filter>Public Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="replaygain_synthesis.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@
#
# GNU makefile
#
topdir = ../../..
libdir = $(topdir)/objs/$(BUILD)/lib
LIB_NAME = libutf8
ifeq ($(OS),Darwin)
EXPLICIT_LIBS = $(libdir)/libgrabbag.a $(ICONV_LIBS)
else
LIBS = -lgrabbag $(ICONV_LIBS)
endif
INCLUDES = -I$(topdir)/include
SRCS_C = \
charset.c \
iconvert.c \
utf8.c
include $(topdir)/build/lib.mk
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,57 @@
/*
* If you need to generate more maps, use makemap.c on a system
* with a decent iconv.
*/
static const unsigned short mapping_iso_8859_2[256] = {
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7,
0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7,
0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
};
static struct {
const char *name;
const unsigned short *map;
struct charset *charset;
} maps[] = {
{ "ISO-8859-2", mapping_iso_8859_2, 0 },
{ 0, 0, 0 }
};
static const struct {
const char *bad;
const char *good;
} names[] = {
{ "ANSI_X3.4-1968", "us-ascii" },
{ 0, 0 }
};

View File

@ -0,0 +1,532 @@
/*
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* See the corresponding header file for a description of the functions
* that this file provides.
*
* This was first written for Ogg Vorbis but could be of general use.
*
* The only deliberate assumption about data sizes is that a short has
* at least 16 bits, but this code has only been tested on systems with
* 8-bit char, 16-bit short and 32-bit int.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if !defined _WIN32 && !defined HAVE_ICONV /* should be && defined USE_CHARSET_CONVERT */
#include <stdlib.h>
#include "share/alloc.h"
#include "charset.h"
#include "charmaps.h"
/*
* This is like the standard strcasecmp, but it does not depend
* on the locale. Locale-dependent functions can be dangerous:
* we once had a bug involving strcasecmp("iso", "ISO") in a
* Turkish locale!
*
* (I'm not really sure what the official standard says
* about the sign of strcasecmp("Z", "["), but usually
* we're only interested in whether it's zero.)
*/
static int ascii_strcasecmp(const char *s1, const char *s2)
{
char c1, c2;
for (;; s1++, s2++) {
if (!*s1 || !*s2)
break;
if (*s1 == *s2)
continue;
c1 = *s1;
if ('a' <= c1 && c1 <= 'z')
c1 += 'A' - 'a';
c2 = *s2;
if ('a' <= c2 && c2 <= 'z')
c2 += 'A' - 'a';
if (c1 != c2)
break;
}
return (unsigned char)*s1 - (unsigned char)*s2;
}
/*
* UTF-8 equivalents of the C library's wctomb() and mbtowc().
*/
int utf8_mbtowc(int *pwc, const char *s, size_t n)
{
unsigned char c;
int wc, i, k;
if (!n || !s)
return 0;
c = *s;
if (c < 0x80) {
if (pwc)
*pwc = c;
return c ? 1 : 0;
}
else if (c < 0xc2)
return -1;
else if (c < 0xe0) {
if (n >= 2 && (s[1] & 0xc0) == 0x80) {
if (pwc)
*pwc = ((c & 0x1f) << 6) | (s[1] & 0x3f);
return 2;
}
else
return -1;
}
else if (c < 0xf0)
k = 3;
else if (c < 0xf8)
k = 4;
else if (c < 0xfc)
k = 5;
else if (c < 0xfe)
k = 6;
else
return -1;
if (n < (size_t)k)
return -1;
wc = *s++ & ((1 << (7 - k)) - 1);
for (i = 1; i < k; i++) {
if ((*s & 0xc0) != 0x80)
return -1;
wc = (wc << 6) | (*s++ & 0x3f);
}
if (wc < (1 << (5 * k - 4)))
return -1;
if (pwc)
*pwc = wc;
return k;
}
int utf8_wctomb(char *s, int wc1)
{
unsigned int wc = wc1;
if (!s)
return 0;
if (wc < (1u << 7)) {
*s++ = wc;
return 1;
}
else if (wc < (1u << 11)) {
*s++ = 0xc0 | (wc >> 6);
*s++ = 0x80 | (wc & 0x3f);
return 2;
}
else if (wc < (1u << 16)) {
*s++ = 0xe0 | (wc >> 12);
*s++ = 0x80 | ((wc >> 6) & 0x3f);
*s++ = 0x80 | (wc & 0x3f);
return 3;
}
else if (wc < (1u << 21)) {
*s++ = 0xf0 | (wc >> 18);
*s++ = 0x80 | ((wc >> 12) & 0x3f);
*s++ = 0x80 | ((wc >> 6) & 0x3f);
*s++ = 0x80 | (wc & 0x3f);
return 4;
}
else if (wc < (1u << 26)) {
*s++ = 0xf8 | (wc >> 24);
*s++ = 0x80 | ((wc >> 18) & 0x3f);
*s++ = 0x80 | ((wc >> 12) & 0x3f);
*s++ = 0x80 | ((wc >> 6) & 0x3f);
*s++ = 0x80 | (wc & 0x3f);
return 5;
}
else if (wc < (1u << 31)) {
*s++ = 0xfc | (wc >> 30);
*s++ = 0x80 | ((wc >> 24) & 0x3f);
*s++ = 0x80 | ((wc >> 18) & 0x3f);
*s++ = 0x80 | ((wc >> 12) & 0x3f);
*s++ = 0x80 | ((wc >> 6) & 0x3f);
*s++ = 0x80 | (wc & 0x3f);
return 6;
}
else
return -1;
}
/*
* The charset "object" and methods.
*/
struct charset {
int max;
int (*mbtowc)(void *table, int *pwc, const char *s, size_t n);
int (*wctomb)(void *table, char *s, int wc);
void *map;
};
int charset_mbtowc(struct charset *charset, int *pwc, const char *s, size_t n)
{
return (*charset->mbtowc)(charset->map, pwc, s, n);
}
int charset_wctomb(struct charset *charset, char *s, int wc)
{
return (*charset->wctomb)(charset->map, s, wc);
}
int charset_max(struct charset *charset)
{
return charset->max;
}
/*
* Implementation of UTF-8.
*/
static int mbtowc_utf8(void *map, int *pwc, const char *s, size_t n)
{
(void)map;
return utf8_mbtowc(pwc, s, n);
}
static int wctomb_utf8(void *map, char *s, int wc)
{
(void)map;
return utf8_wctomb(s, wc);
}
/*
* Implementation of US-ASCII.
* Probably on most architectures this compiles to less than 256 bytes
* of code, so we can save space by not having a table for this one.
*/
static int mbtowc_ascii(void *map, int *pwc, const char *s, size_t n)
{
int wc;
(void)map;
if (!n || !s)
return 0;
wc = (unsigned char)*s;
if (wc & ~0x7f)
return -1;
if (pwc)
*pwc = wc;
return wc ? 1 : 0;
}
static int wctomb_ascii(void *map, char *s, int wc)
{
(void)map;
if (!s)
return 0;
if (wc & ~0x7f)
return -1;
*s = wc;
return 1;
}
/*
* Implementation of ISO-8859-1.
* Probably on most architectures this compiles to less than 256 bytes
* of code, so we can save space by not having a table for this one.
*/
static int mbtowc_iso1(void *map, int *pwc, const char *s, size_t n)
{
int wc;
(void)map;
if (!n || !s)
return 0;
wc = (unsigned char)*s;
if (wc & ~0xff)
return -1;
if (pwc)
*pwc = wc;
return wc ? 1 : 0;
}
static int wctomb_iso1(void *map, char *s, int wc)
{
(void)map;
if (!s)
return 0;
if (wc & ~0xff)
return -1;
*s = wc;
return 1;
}
/*
* Implementation of any 8-bit charset.
*/
struct map {
const unsigned short *from;
struct inverse_map *to;
};
static int mbtowc_8bit(void *map1, int *pwc, const char *s, size_t n)
{
struct map *map = map1;
unsigned short wc;
if (!n || !s)
return 0;
wc = map->from[(unsigned char)*s];
if (wc == 0xffff)
return -1;
if (pwc)
*pwc = (int)wc;
return wc ? 1 : 0;
}
/*
* For the inverse map we use a hash table, which has the advantages
* of small constant memory requirement and simple memory allocation,
* but the disadvantage of slow conversion in the worst case.
* If you need real-time performance while letting a potentially
* malicious user define their own map, then the method used in
* linux/drivers/char/consolemap.c would be more appropriate.
*/
struct inverse_map {
unsigned char first[256];
unsigned char next[256];
};
/*
* The simple hash is good enough for this application.
* Use the alternative trivial hashes for testing.
*/
#define HASH(i) ((i) & 0xff)
/* #define HASH(i) 0 */
/* #define HASH(i) 99 */
static struct inverse_map *make_inverse_map(const unsigned short *from)
{
struct inverse_map *to;
char used[256];
int i, j, k;
to = malloc(sizeof(struct inverse_map));
if (!to)
return 0;
for (i = 0; i < 256; i++)
to->first[i] = to->next[i] = used[i] = 0;
for (i = 255; i >= 0; i--)
if (from[i] != 0xffff) {
k = HASH(from[i]);
to->next[i] = to->first[k];
to->first[k] = i;
used[k] = 1;
}
/* Point the empty buckets at an empty list. */
for (i = 0; i < 256; i++)
if (!to->next[i])
break;
if (i < 256)
for (j = 0; j < 256; j++)
if (!used[j])
to->first[j] = i;
return to;
}
static int wctomb_8bit(void *map1, char *s, int wc1)
{
struct map *map = map1;
unsigned short wc = wc1;
int i;
if (!s)
return 0;
if (wc1 & ~0xffff)
return -1;
if (1) /* Change 1 to 0 to test the case where malloc fails. */
if (!map->to)
map->to = make_inverse_map(map->from);
if (map->to) {
/* Use the inverse map. */
i = map->to->first[HASH(wc)];
for (;;) {
if (map->from[i] == wc) {
*s = i;
return 1;
}
if (!(i = map->to->next[i]))
break;
}
}
else {
/* We don't have an inverse map, so do a linear search. */
for (i = 0; i < 256; i++)
if (map->from[i] == wc) {
*s = i;
return 1;
}
}
return -1;
}
/*
* The "constructor" charset_find().
*/
struct charset charset_utf8 = {
6,
&mbtowc_utf8,
&wctomb_utf8,
0
};
struct charset charset_iso1 = {
1,
&mbtowc_iso1,
&wctomb_iso1,
0
};
struct charset charset_ascii = {
1,
&mbtowc_ascii,
&wctomb_ascii,
0
};
struct charset *charset_find(const char *code)
{
int i;
/* Find good (MIME) name. */
for (i = 0; names[i].bad; i++)
if (!ascii_strcasecmp(code, names[i].bad)) {
code = names[i].good;
break;
}
/* Recognise some charsets for which we avoid using a table. */
if (!ascii_strcasecmp(code, "UTF-8"))
return &charset_utf8;
if (!ascii_strcasecmp(code, "US-ASCII"))
return &charset_ascii;
if (!ascii_strcasecmp(code, "ISO-8859-1"))
return &charset_iso1;
/* Look for a mapping for a simple 8-bit encoding. */
for (i = 0; maps[i].name; i++)
if (!ascii_strcasecmp(code, maps[i].name)) {
if (!maps[i].charset) {
maps[i].charset = malloc(sizeof(struct charset));
if (maps[i].charset) {
struct map *map = malloc(sizeof(struct map));
if (!map) {
free(maps[i].charset);
maps[i].charset = 0;
}
else {
maps[i].charset->max = 1;
maps[i].charset->mbtowc = &mbtowc_8bit;
maps[i].charset->wctomb = &wctomb_8bit;
maps[i].charset->map = map;
map->from = maps[i].map;
map->to = 0; /* inverse mapping is created when required */
}
}
}
return maps[i].charset;
}
return 0;
}
/*
* Function to convert a buffer from one encoding to another.
* Invalid bytes are replaced by '#', and characters that are
* not available in the target encoding are replaced by '?'.
* Each of TO and TOLEN may be zero, if the result is not needed.
* The output buffer is null-terminated, so it is all right to
* use charset_convert(fromcode, tocode, s, strlen(s), &t, 0).
*/
int charset_convert(const char *fromcode, const char *tocode,
const char *from, size_t fromlen,
char **to, size_t *tolen)
{
int ret = 0;
struct charset *charset1, *charset2;
char *tobuf, *p, *newbuf;
int i, j, wc;
charset1 = charset_find(fromcode);
charset2 = charset_find(tocode);
if (!charset1 || !charset2 )
return -1;
tobuf = safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1);
if (!tobuf)
return -2;
for (p = tobuf; fromlen; from += i, fromlen -= i, p += j) {
i = charset_mbtowc(charset1, &wc, from, fromlen);
if (!i)
i = 1;
else if (i == -1) {
i = 1;
wc = '#';
ret = 2;
}
j = charset_wctomb(charset2, p, wc);
if (j == -1) {
if (!ret)
ret = 1;
j = charset_wctomb(charset2, p, '?');
if (j == -1)
j = 0;
}
}
if (tolen)
*tolen = p - tobuf;
*p++ = '\0';
if (to) {
newbuf = realloc(tobuf, p - tobuf);
*to = newbuf ? newbuf : tobuf;
}
else
free(tobuf);
return ret;
}
#endif /* USE_CHARSET_ICONV */

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdlib.h>
/*
* These functions are like the C library's mbtowc() and wctomb(),
* but instead of depending on the locale they always work in UTF-8,
* and they use int instead of wchar_t.
*/
int utf8_mbtowc(int *pwc, const char *s, size_t n);
int utf8_wctomb(char *s, int wc);
/*
* This is an object-oriented version of mbtowc() and wctomb().
* The caller first uses charset_find() to get a pointer to struct
* charset, then uses the mbtowc() and wctomb() methods on it.
* The function charset_max() gives the maximum length of a
* multibyte character in that encoding.
* This API is only appropriate for stateless encodings like UTF-8
* or ISO-8859-3, but I have no intention of implementing anything
* other than UTF-8 and 8-bit encodings.
*
* MINOR BUG: If there is no memory charset_find() may return 0 and
* there is no way to distinguish this case from an unknown encoding.
*/
struct charset;
struct charset *charset_find(const char *code);
int charset_mbtowc(struct charset *charset, int *pwc, const char *s, size_t n);
int charset_wctomb(struct charset *charset, char *s, int wc);
int charset_max(struct charset *charset);
/*
* Function to convert a buffer from one encoding to another.
* Invalid bytes are replaced by '#', and characters that are
* not available in the target encoding are replaced by '?'.
* Each of TO and TOLEN may be zero if the result is not wanted.
* The input or output may contain null bytes, but the output
* buffer is also null-terminated, so it is all right to
* use charset_convert(fromcode, tocode, s, strlen(s), &t, 0).
*
* Return value:
*
* -2 : memory allocation failed
* -1 : unknown encoding
* 0 : data was converted exactly
* 1 : valid data was converted approximately (using '?')
* 2 : input was invalid (but still converted, using '#')
*/
int charset_convert(const char *fromcode, const char *tocode,
const char *from, size_t fromlen,
char **to, size_t *tolen);

View File

@ -0,0 +1,263 @@
/*
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <assert.h>
#include <string.h>
#include "charset.h"
void test_any(struct charset *charset)
{
int wc;
char s[2];
assert(charset);
/* Decoder */
assert(charset_mbtowc(charset, 0, 0, 0) == 0);
assert(charset_mbtowc(charset, 0, 0, 1) == 0);
assert(charset_mbtowc(charset, 0, (char *)(-1), 0) == 0);
assert(charset_mbtowc(charset, 0, "a", 0) == 0);
assert(charset_mbtowc(charset, 0, "", 1) == 0);
assert(charset_mbtowc(charset, 0, "b", 1) == 1);
assert(charset_mbtowc(charset, 0, "", 2) == 0);
assert(charset_mbtowc(charset, 0, "c", 2) == 1);
wc = 'x';
assert(charset_mbtowc(charset, &wc, "a", 0) == 0 && wc == 'x');
assert(charset_mbtowc(charset, &wc, "", 1) == 0 && wc == 0);
assert(charset_mbtowc(charset, &wc, "b", 1) == 1 && wc == 'b');
assert(charset_mbtowc(charset, &wc, "", 2) == 0 && wc == 0);
assert(charset_mbtowc(charset, &wc, "c", 2) == 1 && wc == 'c');
/* Encoder */
assert(charset_wctomb(charset, 0, 0) == 0);
s[0] = s[1] = '.';
assert(charset_wctomb(charset, s, 0) == 1 &&
s[0] == '\0' && s[1] == '.');
assert(charset_wctomb(charset, s, 'x') == 1 &&
s[0] == 'x' && s[1] == '.');
}
void test_utf8()
{
struct charset *charset;
int wc;
char s[8];
charset = charset_find("UTF-8");
test_any(charset);
/* Decoder */
wc = 0;
assert(charset_mbtowc(charset, &wc, "\177", 1) == 1 && wc == 127);
assert(charset_mbtowc(charset, &wc, "\200", 2) == -1);
assert(charset_mbtowc(charset, &wc, "\301\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\302\200", 1) == -1);
assert(charset_mbtowc(charset, &wc, "\302\200", 2) == 2 && wc == 128);
assert(charset_mbtowc(charset, &wc, "\302\200", 3) == 2 && wc == 128);
assert(charset_mbtowc(charset, &wc, "\340\237\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\340\240\200", 9) == 3 &&
wc == 1 << 11);
assert(charset_mbtowc(charset, &wc, "\360\217\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\220\200\200", 9) == 4 &&
wc == 1 << 16);
assert(charset_mbtowc(charset, &wc, "\370\207\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\370\210\200\200\200", 9) == 5 &&
wc == 1 << 21);
assert(charset_mbtowc(charset, &wc, "\374\203\277\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\374\204\200\200\200\200", 9) == 6 &&
wc == 1 << 26);
assert(charset_mbtowc(charset, &wc, "\375\277\277\277\277\277", 9) == 6 &&
wc == 0x7fffffff);
assert(charset_mbtowc(charset, &wc, "\302\000", 2) == -1);
assert(charset_mbtowc(charset, &wc, "\302\300", 2) == -1);
assert(charset_mbtowc(charset, &wc, "\340\040\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\340\340\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\340\240\000", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\340\240\300", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\020\200\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\320\200\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\220\000\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\220\300\200", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\220\200\000", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\360\220\200\300", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\077\277\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\377\277\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\277\077\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\277\377\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\277\277\277\077\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\277\277\277\377\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\277\277\277\277\077", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\375\277\277\277\277\377", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\376\277\277\277\277\277", 9) == -1);
assert(charset_mbtowc(charset, &wc, "\377\277\277\277\277\277", 9) == -1);
/* Encoder */
safe_strncpy(s, ".......", sizeof(s));
assert(charset_wctomb(charset, s, 1 << 31) == -1 &&
!strcmp(s, "......."));
assert(charset_wctomb(charset, s, 127) == 1 &&
!strcmp(s, "\177......"));
assert(charset_wctomb(charset, s, 128) == 2 &&
!strcmp(s, "\302\200....."));
assert(charset_wctomb(charset, s, 0x7ff) == 2 &&
!strcmp(s, "\337\277....."));
assert(charset_wctomb(charset, s, 0x800) == 3 &&
!strcmp(s, "\340\240\200...."));
assert(charset_wctomb(charset, s, 0xffff) == 3 &&
!strcmp(s, "\357\277\277...."));
assert(charset_wctomb(charset, s, 0x10000) == 4 &&
!strcmp(s, "\360\220\200\200..."));
assert(charset_wctomb(charset, s, 0x1fffff) == 4 &&
!strcmp(s, "\367\277\277\277..."));
assert(charset_wctomb(charset, s, 0x200000) == 5 &&
!strcmp(s, "\370\210\200\200\200.."));
assert(charset_wctomb(charset, s, 0x3ffffff) == 5 &&
!strcmp(s, "\373\277\277\277\277.."));
assert(charset_wctomb(charset, s, 0x4000000) == 6 &&
!strcmp(s, "\374\204\200\200\200\200."));
assert(charset_wctomb(charset, s, 0x7fffffff) == 6 &&
!strcmp(s, "\375\277\277\277\277\277."));
}
void test_ascii()
{
struct charset *charset;
int wc;
char s[3];
charset = charset_find("us-ascii");
test_any(charset);
/* Decoder */
wc = 0;
assert(charset_mbtowc(charset, &wc, "\177", 2) == 1 && wc == 127);
assert(charset_mbtowc(charset, &wc, "\200", 2) == -1);
/* Encoder */
safe_strncpy(s, "..", sizeof(s));
assert(charset_wctomb(charset, s, 256) == -1 && !strcmp(s, ".."));
assert(charset_wctomb(charset, s, 255) == -1);
assert(charset_wctomb(charset, s, 128) == -1);
assert(charset_wctomb(charset, s, 127) == 1 && !strcmp(s, "\177."));
}
void test_iso1()
{
struct charset *charset;
int wc;
char s[3];
charset = charset_find("iso-8859-1");
test_any(charset);
/* Decoder */
wc = 0;
assert(charset_mbtowc(charset, &wc, "\302\200", 9) == 1 && wc == 0xc2);
/* Encoder */
safe_strncpy(s, "..", sizeof(s));
assert(charset_wctomb(charset, s, 256) == -1 && !strcmp(s, ".."));
assert(charset_wctomb(charset, s, 255) == 1 && !strcmp(s, "\377."));
assert(charset_wctomb(charset, s, 128) == 1 && !strcmp(s, "\200."));
}
void test_iso2()
{
struct charset *charset;
int wc;
char s[3];
charset = charset_find("iso-8859-2");
test_any(charset);
/* Decoder */
wc = 0;
assert(charset_mbtowc(charset, &wc, "\302\200", 9) == 1 && wc == 0xc2);
assert(charset_mbtowc(charset, &wc, "\377", 2) == 1 && wc == 0x2d9);
/* Encoder */
safe_strncpy(s, "..", sizeof(s));
assert(charset_wctomb(charset, s, 256) == -1 && !strcmp(s, ".."));
assert(charset_wctomb(charset, s, 255) == -1 && !strcmp(s, ".."));
assert(charset_wctomb(charset, s, 258) == 1 && !strcmp(s, "\303."));
assert(charset_wctomb(charset, s, 128) == 1 && !strcmp(s, "\200."));
}
void test_convert()
{
const char *p;
char *q, *r;
char s[256];
size_t n, n2;
int i;
p = "\000x\302\200\375\277\277\277\277\277";
assert(charset_convert("UTF-8", "UTF-8", p, 10, &q, &n) == 0 &&
n == 10 && !strcmp(p, q));
assert(charset_convert("UTF-8", "UTF-8", "x\301\277y", 4, &q, &n) == 2 &&
n == 4 && !strcmp(q, "x##y"));
assert(charset_convert("UTF-8", "UTF-8", "x\301\277y", 4, 0, &n) == 2 &&
n == 4);
assert(charset_convert("UTF-8", "UTF-8", "x\301\277y", 4, &q, 0) == 2 &&
!strcmp(q, "x##y"));
assert(charset_convert("UTF-8", "iso-8859-1",
"\302\200\304\200x", 5, &q, &n) == 1 &&
n == 3 && !strcmp(q, "\200?x"));
assert(charset_convert("iso-8859-1", "UTF-8",
"\000\200\377", 3, &q, &n) == 0 &&
n == 5 && !memcmp(q, "\000\302\200\303\277", 5));
assert(charset_convert("iso-8859-1", "iso-8859-1",
"\000\200\377", 3, &q, &n) == 0 &&
n == 3 && !memcmp(q, "\000\200\377", 3));
assert(charset_convert("iso-8859-2", "utf-8", "\300", 1, &q, &n) == 0 &&
n == 2 && !strcmp(q, "\305\224"));
assert(charset_convert("utf-8", "iso-8859-2", "\305\224", 2, &q, &n) == 0 &&
n == 1 && !strcmp(q, "\300"));
for (i = 0; i < 256; i++)
s[i] = i;
assert(charset_convert("iso-8859-2", "utf-8", s, 256, &q, &n) == 0);
assert(charset_convert("utf-8", "iso-8859-2", q, n, &r, &n2) == 0);
assert(n2 == 256 && !memcmp(r, s, n2));
}
int main()
{
test_utf8();
test_ascii();
test_iso1();
test_iso2();
test_convert();
return 0;
}

View File

@ -0,0 +1,254 @@
/*
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if !defined _WIN32 && defined HAVE_ICONV
#include <assert.h>
#include <errno.h>
#include <iconv.h>
#include <stdlib.h>
#include <string.h>
#include "iconvert.h"
#include "share/alloc.h"
#include "share/safe_str.h"
/*
* Convert data from one encoding to another. Return:
*
* -2 : memory allocation failed
* -1 : unknown encoding
* 0 : data was converted exactly
* 1 : data was converted inexactly
* 2 : data was invalid (but still converted)
*
* We convert in two steps, via UTF-8, as this is the only
* reliable way of distinguishing between invalid input
* and valid input which iconv refuses to transliterate.
* We convert from UTF-8 twice, because we have no way of
* knowing whether the conversion was exact if iconv returns
* E2BIG (due to a bug in the specification of iconv).
* An alternative approach is to assume that the output of
* iconv is never more than 4 times as long as the input,
* but I prefer to avoid that assumption if possible.
*/
int iconvert(const char *fromcode, const char *tocode,
const char *from, size_t fromlen,
char **to, size_t *tolen)
{
int ret = 0;
iconv_t cd1, cd2;
char *ib;
char *ob;
char *utfbuf = 0, *outbuf, *newbuf;
size_t utflen, outlen, ibl, obl, k;
char tbuf[2048];
cd1 = iconv_open("UTF-8", fromcode);
if (cd1 == (iconv_t)(-1))
return -1;
cd2 = (iconv_t)(-1);
/* Don't use strcasecmp() as it's locale-dependent. */
if (!strchr("Uu", tocode[0]) ||
!strchr("Tt", tocode[1]) ||
!strchr("Ff", tocode[2]) ||
tocode[3] != '-' ||
tocode[4] != '8' ||
tocode[5] != '\0') {
char *tocode1;
size_t dest_len = strlen(tocode) + 11;
/*
* Try using this non-standard feature of glibc and libiconv.
* This is deliberately not a config option as people often
* change their iconv library without rebuilding applications.
*/
tocode1 = safe_malloc_(dest_len);
if (!tocode1)
goto fail;
safe_strncpy(tocode1, tocode, dest_len);
safe_strncat(tocode1, "//TRANSLIT", dest_len);
cd2 = iconv_open(tocode1, "UTF-8");
free(tocode1);
if (cd2 == (iconv_t)(-1))
cd2 = iconv_open(tocode, fromcode);
if (cd2 == (iconv_t)(-1)) {
iconv_close(cd1);
return -1;
}
}
utflen = 1; /*fromlen * 2 + 1; XXX */
utfbuf = malloc(utflen);
if (!utfbuf)
goto fail;
/* Convert to UTF-8 */
ib = (char *)from;
ibl = fromlen;
ob = utfbuf;
obl = utflen;
for (;;) {
k = iconv(cd1, &ib, &ibl, &ob, &obl);
assert((!k && !ibl) ||
(k == (size_t)(-1) && errno == E2BIG && ibl && obl < 6) ||
(k == (size_t)(-1) &&
(errno == EILSEQ || errno == EINVAL) && ibl));
if (!ibl)
break;
if (obl < 6) {
/* Enlarge the buffer */
if(utflen*2 < utflen) /* overflow check */
goto fail;
utflen *= 2;
newbuf = realloc(utfbuf, utflen);
if (!newbuf)
goto fail;
ob = (ob - utfbuf) + newbuf;
obl = utflen - (ob - newbuf);
utfbuf = newbuf;
}
else {
/* Invalid input */
ib++, ibl--;
*ob++ = '#', obl--;
ret = 2;
iconv(cd1, 0, 0, 0, 0);
}
}
if (cd2 == (iconv_t)(-1)) {
/* The target encoding was UTF-8 */
if (tolen)
*tolen = ob - utfbuf;
if (!to) {
free(utfbuf);
iconv_close(cd1);
return ret;
}
newbuf = safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
if (!newbuf)
goto fail;
ob = (ob - utfbuf) + newbuf;
*ob = '\0';
*to = newbuf;
iconv_close(cd1);
return ret;
}
/* Truncate the buffer to be tidy */
utflen = ob - utfbuf;
newbuf = realloc(utfbuf, utflen);
if (!newbuf)
goto fail;
utfbuf = newbuf;
/* Convert from UTF-8 to discover how long the output is */
outlen = 0;
ib = utfbuf;
ibl = utflen;
while (ibl) {
ob = tbuf;
obl = sizeof(tbuf);
k = iconv(cd2, &ib, &ibl, &ob, &obl);
assert((k != (size_t)(-1) && !ibl) ||
(k == (size_t)(-1) && errno == E2BIG && ibl) ||
(k == (size_t)(-1) && errno == EILSEQ && ibl));
if (ibl && !(k == (size_t)(-1) && errno == E2BIG)) {
/* Replace one character */
char *tb = "?";
size_t tbl = 1;
outlen += ob - tbuf;
ob = tbuf;
obl = sizeof(tbuf);
k = iconv(cd2, &tb, &tbl, &ob, &obl);
assert((!k && !tbl) ||
(k == (size_t)(-1) && errno == EILSEQ && tbl));
for (++ib, --ibl; ibl && (*ib & 0x80); ib++, ibl--)
;
}
outlen += ob - tbuf;
}
ob = tbuf;
obl = sizeof(tbuf);
k = iconv(cd2, 0, 0, &ob, &obl);
assert(!k);
outlen += ob - tbuf;
/* Convert from UTF-8 for real */
outbuf = safe_malloc_add_2op_(outlen, /*+*/1);
if (!outbuf)
goto fail;
ib = utfbuf;
ibl = utflen;
ob = outbuf;
obl = outlen;
while (ibl) {
k = iconv(cd2, &ib, &ibl, &ob, &obl);
assert((k != (size_t)(-1) && !ibl) ||
(k == (size_t)(-1) && errno == EILSEQ && ibl));
if (k && !ret)
ret = 1;
if (ibl && !(k == (size_t)(-1) && errno == E2BIG)) {
/* Replace one character */
char *tb = "?";
size_t tbl = 1;
k = iconv(cd2, &tb, &tbl, &ob, &obl);
assert((!k && !tbl) ||
(k == (size_t)(-1) && errno == EILSEQ && tbl));
for (++ib, --ibl; ibl && (*ib & 0x80); ib++, ibl--)
;
}
}
k = iconv(cd2, 0, 0, &ob, &obl);
assert(!k);
assert(!obl);
*ob = '\0';
free(utfbuf);
iconv_close(cd1);
iconv_close(cd2);
if (tolen)
*tolen = outlen;
if (!to) {
free(outbuf);
return ret;
}
*to = outbuf;
return ret;
fail:
if(0 != utfbuf)
free(utfbuf);
iconv_close(cd1);
if (cd2 != (iconv_t)(-1))
iconv_close(cd2);
return -2;
}
#endif /* HAVE_ICONV */

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_ICONV
/*
* Convert data from one encoding to another. Return:
*
* -2 : memory allocation failed
* -1 : unknown encoding
* 0 : data was converted exactly
* 1 : data was converted inexactly
* 2 : data was invalid (but still converted)
*
* We convert in two steps, via UTF-8, as this is the only
* reliable way of distinguishing between invalid input
* and valid input which iconv refuses to transliterate.
* We convert from UTF-8 twice, because we have no way of
* knowing whether the conversion was exact if iconv returns
* E2BIG (due to a bug in the specification of iconv).
* An alternative approach is to assume that the output of
* iconv is never more than 4 times as long as the input,
* but I prefer to avoid that assumption if possible.
*/
int iconvert(const char *fromcode, const char *tocode,
const char *from, size_t fromlen,
char **to, size_t *tolen) ;
#endif /* HAVE_ICONV */

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <iconv.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
iconv_t cd;
const char *ib;
char *ob;
size_t ibl, obl, k;
unsigned char c, buf[4];
int i, wc;
if (argc != 2) {
printf("Usage: %s ENCODING\n", argv[0]);
printf("Output a charset map for the 8-bit ENCODING.\n");
return 1;
}
cd = iconv_open("UCS-4", argv[1]);
if (cd == (iconv_t)(-1)) {
perror("iconv_open");
return 1;
}
for (i = 0; i < 256; i++) {
c = i;
ib = &c;
ibl = 1;
ob = buf;
obl = 4;
k = iconv(cd, &ib, &ibl, &ob, &obl);
if (!k && !ibl && !obl) {
wc = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
if (wc >= 0xffff) {
printf("Dodgy value.\n");
return 1;
}
}
else if (k == (size_t)(-1) && errno == EILSEQ)
wc = 0xffff;
else {
printf("Non-standard iconv.\n");
return 1;
}
if (i % 8 == 0)
printf(" ");
printf("0x%04x", wc);
if (i == 255)
printf("\n");
else if (i % 8 == 7)
printf(",\n");
else
printf(", ");
}
return 0;
}

View File

@ -0,0 +1,209 @@
/*
* Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com>
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
*
* Buffer overflow checking added: Josh Coalson, 9/9/2007
*
* Win32 part rewritten: lvqcl, 2/2/2016
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Convert a string between UTF-8 and the locale's charset.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include "share/alloc.h"
#include "share/utf8.h"
#ifdef _WIN32
#include <windows.h>
int utf8_encode(const char *from, char **to)
{
wchar_t *unicode = NULL;
char *utf8 = NULL;
int ret = -1;
do {
int len;
len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, -1, NULL, 0);
if(len == 0) break;
unicode = (wchar_t*) safe_malloc_mul_2op_((size_t)len, sizeof(wchar_t));
if(unicode == NULL) break;
len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, -1, unicode, len);
if(len == 0) break;
len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
if(len == 0) break;
utf8 = (char*) safe_malloc_mul_2op_((size_t)len, sizeof(char));
if(utf8 == NULL) break;
len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, len, NULL, NULL);
if(len == 0) break;
ret = 0;
} while(0);
free(unicode);
if(ret == 0) {
*to = utf8;
} else {
free(utf8);
*to = NULL;
}
return ret;
}
int utf8_decode(const char *from, char **to)
{
wchar_t *unicode = NULL;
char *acp = NULL;
int ret = -1;
do {
int len;
len = MultiByteToWideChar(CP_UTF8, 0, from, -1, NULL, 0);
if(len == 0) break;
unicode = (wchar_t*) safe_malloc_mul_2op_((size_t)len, sizeof(wchar_t));
if(unicode == NULL) break;
len = MultiByteToWideChar(CP_UTF8, 0, from, -1, unicode, len);
if(len == 0) break;
len = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL);
if(len == 0) break;
acp = (char*) safe_malloc_mul_2op_((size_t)len, sizeof(char));
if(acp == NULL) break;
len = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, acp, len, NULL, NULL);
if(len == 0) break;
ret = 0;
} while(0);
free(unicode);
if(ret == 0) {
*to = acp;
} else {
free(acp);
*to = NULL;
}
return ret;
}
#else /* End win32. Rest is for real operating systems */
#ifdef HAVE_LANGINFO_CODESET
#include <langinfo.h>
#endif
#include <string.h>
#include "share/safe_str.h"
#include "iconvert.h"
#include "charset.h"
static const char *current_charset(void)
{
const char *c = 0;
#ifdef HAVE_LANGINFO_CODESET
c = nl_langinfo(CODESET);
#endif
if (!c)
c = getenv("CHARSET");
return c? c : "US-ASCII";
}
static int convert_buffer(const char *fromcode, const char *tocode,
const char *from, size_t fromlen,
char **to, size_t *tolen)
{
int ret = -1;
#ifdef HAVE_ICONV
ret = iconvert(fromcode, tocode, from, fromlen, to, tolen);
if (ret != -1)
return ret;
#endif
#ifndef HAVE_ICONV /* should be ifdef USE_CHARSET_CONVERT */
ret = charset_convert(fromcode, tocode, from, fromlen, to, tolen);
if (ret != -1)
return ret;
#endif
return ret;
}
static int convert_string(const char *fromcode, const char *tocode,
const char *from, char **to, char replace)
{
int ret;
size_t fromlen;
char *s;
fromlen = strlen(from);
ret = convert_buffer(fromcode, tocode, from, fromlen, to, 0);
if (ret == -2)
return -1;
if (ret != -1)
return ret;
s = safe_malloc_add_2op_(fromlen, /*+*/1);
if (!s)
return -1;
safe_strncpy(s, from, fromlen + 1);
*to = s;
for (; *s; s++)
if (*s & ~0x7f)
*s = replace;
return 3;
}
int utf8_encode(const char *from, char **to)
{
return convert_string(current_charset(), "UTF-8", from, to, '#');
}
int utf8_decode(const char *from, char **to)
{
return convert_string("UTF-8", current_charset(), from, to, '?');
}
#endif

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="utf8_static"
ProjectGUID="{4cefbc92-c215-11db-8314-0800200c9a66}"
RootNamespace="utf8_static"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Public Header Files"
>
<File
RelativePath="..\..\..\include\share\utf8.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\utf8.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4cefbc92-c215-11db-8314-0800200c9a66}</ProjectGuid>
<RootNamespace>utf8_static</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\utf8.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="utf8.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Public Header Files">
<UniqueIdentifier>{c96e2c5d-a952-4c1d-b3d7-294a5b216154}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\utf8.h">
<Filter>Public Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="utf8.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,21 @@
#
# GNU makefile
#
topdir = ../../..
ifeq ($(OS),Darwin)
EXPLICIT_LIBS = $(libdir)/libFLAC.a $(OGG_EXPLICIT_LIBS) -lm
else
LIBS = -lFLAC $(OGG_LIBS) -lm
endif
LIB_NAME = libwin_utf8_io
INCLUDES = -I$(topdir)/include
SRCS_C = \
win_utf8_io.c
include $(topdir)/build/lib.mk
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,253 @@
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2013-2016 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <windows.h>
#include "share/win_utf8_io.h"
#include "share/windows_unicode_filenames.h"
#define UTF8_BUFFER_SIZE 32768
static int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
{
int rc;
#if defined _MSC_VER
if (size == 0)
return 1024;
rc = vsnprintf_s(str, size, _TRUNCATE, fmt, va);
if (rc < 0)
rc = size - 1;
#elif defined __MINGW32__
rc = __mingw_vsnprintf(str, size, fmt, va);
#else
rc = vsnprintf(str, size, fmt, va);
#endif
return rc;
}
/* convert WCHAR stored Unicode string to UTF-8. Caller is responsible for freeing memory */
static char *utf8_from_wchar(const wchar_t *wstr)
{
char *utf8str;
int len;
if (!wstr)
return NULL;
if ((len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL)) == 0)
return NULL;
if ((utf8str = (char *)malloc(len)) == NULL)
return NULL;
if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8str, len, NULL, NULL) == 0) {
free(utf8str);
utf8str = NULL;
}
return utf8str;
}
/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */
static wchar_t *wchar_from_utf8(const char *str)
{
wchar_t *widestr;
int len;
if (!str)
return NULL;
if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0)
return NULL;
if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL)
return NULL;
if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) {
free(widestr);
widestr = NULL;
}
return widestr;
}
/* retrieve WCHAR commandline, expand wildcards and convert everything to UTF-8 */
int get_utf8_argv(int *argc, char ***argv)
{
typedef int (__cdecl *wgetmainargs_t)(int*, wchar_t***, wchar_t***, int, int*);
wgetmainargs_t wgetmainargs;
HMODULE handle;
int wargc;
wchar_t **wargv;
wchar_t **wenv;
char **utf8argv;
int ret, i;
if ((handle = LoadLibrary("msvcrt.dll")) == NULL) return 1;
if ((wgetmainargs = (wgetmainargs_t)GetProcAddress(handle, "__wgetmainargs")) == NULL) {
FreeLibrary(handle);
return 1;
}
i = 0;
/* when the 4th argument is 1, __wgetmainargs expands wildcards but also erroneously converts \\?\c:\path\to\file.flac to \\file.flac */
if (wgetmainargs(&wargc, &wargv, &wenv, 1, &i) != 0) {
FreeLibrary(handle);
return 1;
}
if ((utf8argv = (char **)calloc(wargc, sizeof(char*))) == NULL) {
FreeLibrary(handle);
return 1;
}
ret = 0;
for (i=0; i<wargc; i++) {
if ((utf8argv[i] = utf8_from_wchar(wargv[i])) == NULL) {
ret = 1;
break;
}
}
FreeLibrary(handle); /* do not free it when wargv or wenv are still in use */
if (ret == 0) {
flac_set_utf8_filenames(true);
*argc = wargc;
*argv = utf8argv;
} else {
for (i=0; i<wargc; i++)
free(utf8argv[i]);
free(utf8argv);
}
return ret;
}
/* return number of characters in the UTF-8 string */
size_t strlen_utf8(const char *str)
{
size_t len;
len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); /* includes terminating null */
if (len != 0)
return len-1;
else
return strlen(str);
}
/* get the console width in characters */
int win_get_console_width(void)
{
int width = 80;
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if(hOut != INVALID_HANDLE_VALUE && hOut != NULL)
if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0)
width = csbi.dwSize.X;
return width;
}
/* print functions */
static int wprint_console(FILE *stream, const wchar_t *text, size_t len)
{
DWORD out;
int ret;
do {
if (stream == stdout) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE || hOut == NULL || GetFileType(hOut) != FILE_TYPE_CHAR)
break;
if (WriteConsoleW(hOut, text, len, &out, NULL) == 0)
return -1;
return out;
}
if (stream == stderr) {
HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE);
if (hErr == INVALID_HANDLE_VALUE || hErr == NULL || GetFileType(hErr) != FILE_TYPE_CHAR)
break;
if (WriteConsoleW(hErr, text, len, &out, NULL) == 0)
return -1;
return out;
}
} while(0);
ret = fputws(text, stream);
if (ret < 0)
return ret;
return len;
}
int printf_utf8(const char *format, ...)
{
int ret;
va_list argptr;
va_start(argptr, format);
ret = vfprintf_utf8(stdout, format, argptr);
va_end(argptr);
return ret;
}
int fprintf_utf8(FILE *stream, const char *format, ...)
{
int ret;
va_list argptr;
va_start(argptr, format);
ret = vfprintf_utf8(stream, format, argptr);
va_end(argptr);
return ret;
}
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr)
{
char *utmp = NULL;
wchar_t *wout = NULL;
int ret = -1;
do {
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE))) break;
if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) <= 0) break;
if (!(wout = wchar_from_utf8(utmp))) {
ret = -1;
break;
}
ret = wprint_console(stream, wout, wcslen(wout));
} while(0);
free(utmp);
free(wout);
return ret;
}

View File

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="win_utf8_io_static"
ProjectGUID="{4cefbe02-c215-11db-8314-0800200c9a66}"
RootNamespace="win_utf8_io_static"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)objs\$(ConfigurationName)\lib"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories=".\include;..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;FLAC__NO_DLL"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings="4267;4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Public Header Files"
>
<File
RelativePath="..\..\..\include\share\win_utf8_io.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\win_utf8_io.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4cefbe02-c215-11db-8314-0800200c9a66}</ProjectGuid>
<RootNamespace>win_utf8_io_static</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)objs\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)objs\$(Platform)\$(Configuration)\lib\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;FLAC__NO_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.\include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;FLAC__NO_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\win_utf8_io.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="win_utf8_io.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Public Header Files">
<UniqueIdentifier>{6469e7f2-0837-4004-9f36-27d45ed62336}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\include\share\win_utf8_io.h">
<Filter>Public Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="win_utf8_io.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>