diff --git a/.bzrignore b/.bzrignore
index 513346a1..6c9ff988 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -18,13 +18,13 @@ Makefile
Makefile.in
aclocal.m4
autom4te.cache
-compile
-config.guess
+Cfg/compile
+Cfg/config.guess
config.log
config.status
-config.sub
+Cfg/config.sub
configure
-depcomp
+Cfg/depcomp
doc/libsndfile.css
examples/cooledit-fixer
examples/generate
@@ -35,12 +35,12 @@ examples/sndfile-convert
examples/sndfile-data-trim
examples/sndfile-info
examples/sndfile-play
-install-sh
+Cfg/install-sh
libsndfile-1.0.*pre*
libsndfile.spec
libtool
-ltmain.sh
-missing
+Cfg/ltmain.sh
+Cfg/missing
regtest/sndfile-regtest
sndfile.pc
src/*sndfile.def
@@ -83,3 +83,4 @@ tests/utils.c
tests/utils.h
tests/write_read_test.c
src/FLAC/src/test_libFLAC/matrix
+*.oct
diff --git a/ChangeLog b/ChangeLog
index c3e4f147..a60a48b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,115 @@
+2007-10-21 Erik de Castro Lopo
+
+ * src/sndfile.h.in src/sndfile.c
+ Add command SFC_GET_CURRENT_SF_INFO.
+
+ * src/sndfile.h.in src/sndfile.c src/create_symbols_file.py
+ Remove function sf_get_info (only ever in pre-release code).
+
+ * tests/command_test.c
+ Add test for SFC_GET_CURRENT_SF_INFO.
+
+2007-10-15 Erik de Castro Lopo
+
+ * src/wav.c
+ Add parsing of 'exif' chunks. Originally coded by Trent Apted.
+
+ * configure.ac
+ Put config stuff in Cfg directory.
+ Remove check for inttypes.h.
+
+2007-10-10 Erik de Castro Lopo
+
+ * src/w64.c
+ Fix writing of 'riff' chunk length and check for correct value in parser.
+
+2007-09-20 Erik de Castro Lopo
+
+ * doc/index.html
+ Link to MP3 FAQ entry.
+
+2007-09-18 Erik de Castro Lopo
+
+ * src/flac.c
+ Move the blocksize check to an earlier stage of flac_buffer_copy.
+
+2007-09-12 Erik de Castro Lopo
+
+ * src/FLAC
+ Huge merge from FLAC upstream.
+
+2007-09-10 Erik de Castro Lopo
+
+ * examples/*.c
+ Change license to all example programs to BSD.
+
+2007-09-08 Erik de Castro Lopo
+
+ * src/FLAC/include/FLAC/metadata.h
+ Include to prevent compile error on OSX.
+
+ * Octave/octave_test.sh
+ Disable test on OSX. Can't get it to work.
+
+ * src/flac.c
+ Check the blocksize returned from the FLAC decoder to prevent buffer
+ overruns. Reported by Jeremy Friesner. Thanks.
+
+2007-09-07 Erik de Castro Lopo
+
+ * Makefile.am M4/octave.m4
+ Fix build when Octave headers are not present.
+
+2007-08-27 Erik de Castro Lopo
+
+ * doc/development.html
+ Add note about bzr repository directory looking empty.
+
+2007-08-26 Erik de Castro Lopo
+
+ * configure.ac Octave/* M4/octave_*
+ Bunch of changes to add ability to build GNU Octave modules to read/write
+ sound files using libsndfile from Octave.
+
+2007-08-23 Erik de Castro Lopo
+
+ * acinclude.m4 configure.ac ...
+ Get rid of acinclude.m4 and replace it with an M4 directory.
+
+2007-08-21 Erik de Castro Lopo
+
+ * src/sndfile.h.in
+ Remove crufty Metrowerks compiler support. Allow header file to be compiled
+ on windows with both GCC and microsoft compiler.
+
+2007-08-19 Erik de Castro Lopo
+
+ * tests/dft_cmp.[ch] tests/floating_point_test.tpl
+ Clean up floating point tests.
+
+2007-08-14 Erik de Castro Lopo
+
+ * src/aiff.c
+ Fix segfault when COMM chunk length is byte swapped.
+
+2007-08-09 Erik de Castro Lopo
+
+ * src/common.h src/mat4.c src/mat5.c src/sndfile.c
+ Add a generic SFE_CHANNEL_COUNT_ZERO error, remove format specific errors.
+
+ * src/au.c
+ Fix crash on AU files with zero channel count. Reported by Ben Alison.
+
+2007-08-08 Erik de Castro Lopo
+
+ * src/voc.c
+ Fix bug in handling file supplied by Matt Olenik.
+
+2007-07-31 Erik de Castro Lopo
+
+ * src/OGG
+ Merge from OGG upstream sources.
+
2007-07-25 Erik de Castro Lopo
* src/FLAC
diff --git a/M4/Makefile.am b/M4/Makefile.am
new file mode 100644
index 00000000..3ea1b7fb
--- /dev/null
+++ b/M4/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = add_cflags.m4 clip_mode.m4 endian.m4 extra_largefile.m4 \
+ flexible_array.m4 llrint.m4 lrint.m4 lrintf.m4 octave.m4
+
diff --git a/M4/add_cflags.m4 b/M4/add_cflags.m4
new file mode 100644
index 00000000..eeb6efda
--- /dev/null
+++ b/M4/add_cflags.m4
@@ -0,0 +1,15 @@
+dnl @synopsis AC_ADD_CFLAGS
+dnl
+dnl Add the given option to CFLAGS, if it doesn't break the compiler
+
+AC_DEFUN([AC_ADD_CFLAGS],
+[AC_MSG_CHECKING([if $CC accepts $1])
+ ac_add_cflags__old_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_TRY_LINK([#include ],
+ [puts("Hello, World!"); return 0;],
+ AC_MSG_RESULT([yes]),
+ AC_MSG_RESULT([no])
+ CFLAGS="$ac_add_cflags__old_cflags")
+ ])
+])# AC_ADD_CFLAGS
diff --git a/M4/clip_mode.m4 b/M4/clip_mode.m4
new file mode 100644
index 00000000..57c94a96
--- /dev/null
+++ b/M4/clip_mode.m4
@@ -0,0 +1,124 @@
+dnl @synopsis AC_C_CLIP_MODE
+dnl
+dnl Determine the clipping mode when converting float to int.
+dnl @version 1.0 May 17 2003
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+
+
+
+
+
+
+
+dnl Find the clipping mode in the following way:
+dnl 1) If we are not cross compiling test it.
+dnl 2) IF we are cross compiling, assume that clipping isn't done correctly.
+
+AC_DEFUN([AC_C_CLIP_MODE],
+[AC_CACHE_CHECK(processor clipping capabilities,
+ ac_cv_c_clip_type,
+
+# Initialize to unknown
+ac_cv_c_clip_positive=unknown
+ac_cv_c_clip_negative=unknown
+
+
+if test $ac_cv_c_clip_positive = unknown ; then
+ AC_TRY_RUN(
+ [[
+ #define _ISOC9X_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #define __USE_ISOC99 1
+ #define __USE_ISOC9X 1
+ #include
+ int main (void)
+ { double fval ;
+ int k, ival ;
+
+ fval = 1.0 * 0x7FFFFFFF ;
+ for (k = 0 ; k < 100 ; k++)
+ { ival = (lrint (fval)) >> 24 ;
+ if (ival != 127)
+ return 1 ;
+
+ fval *= 1.2499999 ;
+ } ;
+
+ return 0 ;
+ }
+ ]],
+ ac_cv_c_clip_positive=yes,
+ ac_cv_c_clip_positive=no,
+ ac_cv_c_clip_positive=unknown
+ )
+
+ AC_TRY_RUN(
+ [[
+ #define _ISOC9X_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #define __USE_ISOC99 1
+ #define __USE_ISOC9X 1
+ #include
+ int main (void)
+ { double fval ;
+ int k, ival ;
+
+ fval = -8.0 * 0x10000000 ;
+ for (k = 0 ; k < 100 ; k++)
+ { ival = (lrint (fval)) >> 24 ;
+ if (ival != -128)
+ return 1 ;
+
+ fval *= 1.2499999 ;
+ } ;
+
+ return 0 ;
+ }
+ ]],
+ ac_cv_c_clip_negative=yes,
+ ac_cv_c_clip_negative=no,
+ ac_cv_c_clip_negative=unknown
+ )
+ fi
+
+if test $ac_cv_c_clip_positive = yes ; then
+ ac_cv_c_clip_positive=1
+else
+ ac_cv_c_clip_positive=0
+ fi
+
+if test $ac_cv_c_clip_negative = yes ; then
+ ac_cv_c_clip_negative=1
+else
+ ac_cv_c_clip_negative=0
+ fi
+
+[[
+case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in
+ "00")
+ ac_cv_c_clip_type="none"
+ ;;
+ "10")
+ ac_cv_c_clip_type="positive"
+ ;;
+ "01")
+ ac_cv_c_clip_type="negative"
+ ;;
+ "11")
+ ac_cv_c_clip_type="both"
+ ;;
+ esac
+ ]]
+
+)
+]
+
+)# AC_C_CLIP_MODE
+
+
diff --git a/M4/endian.m4 b/M4/endian.m4
new file mode 100644
index 00000000..df91ecc3
--- /dev/null
+++ b/M4/endian.m4
@@ -0,0 +1,159 @@
+dnl @synopsis AC_C_FIND_ENDIAN
+dnl
+dnl Determine endian-ness of target processor.
+dnl @version 1.1 Mar 03 2002
+dnl @author Erik de Castro Lopo
+dnl
+dnl Majority written from scratch to replace the standard autoconf macro
+dnl AC_C_BIGENDIAN. Only part remaining from the original it the invocation
+dnl of the AC_TRY_RUN macro.
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+
+dnl Find endian-ness in the following way:
+dnl 1) Look in .
+dnl 2) If 1) fails, look in and .
+dnl 3) If 1) and 2) fails and not cross compiling run a test program.
+dnl 4) If 1) and 2) fails and cross compiling then guess based on target.
+
+AC_DEFUN([AC_C_FIND_ENDIAN],
+[AC_CACHE_CHECK(processor byte ordering,
+ ac_cv_c_byte_order,
+
+# Initialize to unknown
+ac_cv_c_byte_order=unknown
+
+if test x$ac_cv_header_endian_h = xyes ; then
+
+ # First try which should set BYTE_ORDER.
+
+ [AC_TRY_LINK([
+ #include
+ #if BYTE_ORDER != LITTLE_ENDIAN
+ not big endian
+ #endif
+ ], return 0 ;,
+ ac_cv_c_byte_order=little
+ )]
+
+ [AC_TRY_LINK([
+ #include
+ #if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+ ], return 0 ;,
+ ac_cv_c_byte_order=big
+ )]
+
+ fi
+
+if test $ac_cv_c_byte_order = unknown ; then
+
+ [AC_TRY_LINK([
+ #include
+ #include
+ #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+ #endif
+ ], return 0 ;,
+
+ [AC_TRY_LINK([
+ #include
+ #include
+ #if BYTE_ORDER != LITTLE_ENDIAN
+ not big endian
+ #endif
+ ], return 0 ;,
+ ac_cv_c_byte_order=little
+ )]
+
+ [AC_TRY_LINK([
+ #include
+ #include
+ #if BYTE_ORDER != LITTLE_ENDIAN
+ not big endian
+ #endif
+ ], return 0 ;,
+ ac_cv_c_byte_order=little
+ )]
+
+ )]
+
+ fi
+
+if test $ac_cv_c_byte_order = unknown ; then
+ if test $cross_compiling = yes ; then
+ # This is the last resort. Try to guess the target processor endian-ness
+ # by looking at the target CPU type.
+ [
+ case "$target_cpu" in
+ alpha* | i?86* | mipsel* | ia64*)
+ ac_cv_c_big_endian=0
+ ac_cv_c_little_endian=1
+ ;;
+
+ m68* | mips* | powerpc* | hppa* | sparc*)
+ ac_cv_c_big_endian=1
+ ac_cv_c_little_endian=0
+ ;;
+
+ esac
+ ]
+ else
+ AC_TRY_RUN(
+ [[
+ int main (void)
+ { /* Are we little or big endian? From Harbison&Steele. */
+ union
+ { long l ;
+ char c [sizeof (long)] ;
+ } u ;
+ u.l = 1 ;
+ return (u.c [sizeof (long) - 1] == 1);
+ }
+ ]], , ac_cv_c_byte_order=big,
+ ac_cv_c_byte_order=unknown
+ )
+
+ AC_TRY_RUN(
+ [[int main (void)
+ { /* Are we little or big endian? From Harbison&Steele. */
+ union
+ { long l ;
+ char c [sizeof (long)] ;
+ } u ;
+ u.l = 1 ;
+ return (u.c [0] == 1);
+ }]], , ac_cv_c_byte_order=little,
+ ac_cv_c_byte_order=unknown
+ )
+ fi
+ fi
+
+)
+]
+
+if test $ac_cv_c_byte_order = big ; then
+ ac_cv_c_big_endian=1
+ ac_cv_c_little_endian=0
+elif test $ac_cv_c_byte_order = little ; then
+ ac_cv_c_big_endian=0
+ ac_cv_c_little_endian=1
+else
+ ac_cv_c_big_endian=0
+ ac_cv_c_little_endian=0
+
+ AC_MSG_WARN([[*****************************************************************]])
+ AC_MSG_WARN([[*** Not able to determine endian-ness of target processor. ]])
+ AC_MSG_WARN([[*** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in ]])
+ AC_MSG_WARN([[*** src/config.h may need to be hand editied. ]])
+ AC_MSG_WARN([[*****************************************************************]])
+ fi
+
+)# AC_C_FIND_ENDIAN
+
+
diff --git a/M4/extra_largefile.m4 b/M4/extra_largefile.m4
new file mode 100644
index 00000000..47401f85
--- /dev/null
+++ b/M4/extra_largefile.m4
@@ -0,0 +1,114 @@
+dnl By default, many hosts won't let programs access large files;
+dnl one must use special compiler options to get large-file access to work.
+dnl For more details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert .
+
+dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
+dnl AC_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME)
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_FLAGS],
+ [AC_CACHE_CHECK([for $1 value to request large file support],
+ ac_cv_sys_largefile_$1,
+ [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || {
+ ac_cv_sys_largefile_$1=no
+ ifelse($1, CFLAGS,
+ [case "$host_os" in
+ # IRIX 6.2 and later require cc -n32.
+changequote(, )dnl
+ irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*)
+changequote([, ])dnl
+ if test "$GCC" != yes; then
+ ac_cv_sys_largefile_CFLAGS=-n32
+ fi
+ ac_save_CC="$CC"
+ CC="$CC $ac_cv_sys_largefile_CFLAGS"
+ AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no)
+ CC="$ac_save_CC"
+ esac])
+ }])])
+
+dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
+dnl AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(VAR, VAL)
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND],
+ [case $2 in
+ no) ;;
+ ?*)
+ case "[$]$1" in
+ '') $1=$2 ;;
+ *) $1=[$]$1' '$2 ;;
+ esac ;;
+ esac])
+
+dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
+dnl AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT)
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE],
+ [AC_CACHE_CHECK([for $1], $2,
+ [$2=no
+changequote(, )dnl
+ $4
+ for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+ case "$ac_flag" in
+ -D$1)
+ $2=1 ;;
+ -D$1=*)
+ $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
+ esac
+ done
+changequote([, ])dnl
+ ])
+ if test "[$]$2" != no; then
+ AC_DEFINE_UNQUOTED([$1], [$]$2, [$3])
+ fi])
+
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE],
+ [AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_ARG_ENABLE(largefile,
+ [ --disable-largefile omit support for large files])
+ if test "$enable_largefile" != no; then
+ AC_CHECK_TOOL(GETCONF, getconf)
+ AC_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS)
+ AC_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS)
+ AC_SYS_EXTRA_LARGEFILE_FLAGS(LIBS)
+
+ for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+ case "$ac_flag" in
+ no) ;;
+ -D_FILE_OFFSET_BITS=*) ;;
+ -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;;
+ -D_LARGE_FILES | -D_LARGE_FILES=*) ;;
+ -D?* | -I?*)
+ AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;;
+ *)
+ AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;;
+ esac
+ done
+ AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS")
+ AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS")
+ AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS,
+ ac_cv_sys_file_offset_bits,
+ [Number of bits in a file offset, on hosts where this is settable.])
+ [case "$host_os" in
+ # HP-UX 10.20 and later
+ hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
+ ac_cv_sys_file_offset_bits=64 ;;
+ esac]
+ AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE,
+ ac_cv_sys_largefile_source,
+ [Define to make fseeko etc. visible, on some hosts.],
+ [case "$host_os" in
+ # HP-UX 10.20 and later
+ hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
+ ac_cv_sys_largefile_source=1 ;;
+ esac])
+ AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGE_FILES,
+ ac_cv_sys_large_files,
+ [Define for large files, on AIX-style hosts.],
+ [case "$host_os" in
+ # AIX 4.2 and later
+ aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*)
+ ac_cv_sys_large_files=1 ;;
+ esac])
+ fi
+ ])
+
diff --git a/M4/flexible_array.m4 b/M4/flexible_array.m4
new file mode 100644
index 00000000..7f558d3e
--- /dev/null
+++ b/M4/flexible_array.m4
@@ -0,0 +1,32 @@
+dnl @synopsis AC_C99_FLEXIBLE_ARRAY
+dnl
+dnl Dose the compiler support the 1999 ISO C Standard "stuct hack".
+dnl @version 1.1 Mar 15 2004
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+
+AC_DEFUN([AC_C99_FLEXIBLE_ARRAY],
+[AC_CACHE_CHECK(C99 struct flexible array support,
+ ac_cv_c99_flexible_array,
+
+# Initialize to unknown
+ac_cv_c99_flexible_array=no
+
+AC_TRY_LINK([[
+ #include
+ typedef struct {
+ int k;
+ char buffer [] ;
+ } MY_STRUCT ;
+ ]],
+ [ MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42); ],
+ ac_cv_c99_flexible_array=yes,
+ ac_cv_c99_flexible_array=no
+ ))]
+) # AC_C99_FLEXIBLE_ARRAY
+
diff --git a/M4/llrint.m4 b/M4/llrint.m4
new file mode 100644
index 00000000..0f5ce698
--- /dev/null
+++ b/M4/llrint.m4
@@ -0,0 +1,38 @@
+dnl @synopsis AC_C99_FUNC_LLRINT
+dnl
+dnl Check whether C99's llrint function is available.
+dnl @version 1.1 Sep 30 2002
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LLRINT],
+[AC_CACHE_CHECK(for llrint,
+ ac_cv_c99_llrint,
+[
+llrint_save_CFLAGS=$CFLAGS
+CFLAGS="-lm"
+AC_TRY_LINK([
+#define _ISOC9X_SOURCE 1
+#define _ISOC99_SOURCE 1
+#define __USE_ISOC99 1
+#define __USE_ISOC9X 1
+
+#include
+#include
+], int64_t x ; x = llrint(3.14159) ;, ac_cv_c99_llrint=yes, ac_cv_c99_llrint=no)
+
+CFLAGS=$llrint_save_CFLAGS
+
+])
+
+if test "$ac_cv_c99_llrint" = yes; then
+ AC_DEFINE(HAVE_LLRINT, 1,
+ [Define if you have C99's llrint function.])
+fi
+])# AC_C99_FUNC_LLRINT
+
diff --git a/M4/lrint.m4 b/M4/lrint.m4
new file mode 100644
index 00000000..3e3319e1
--- /dev/null
+++ b/M4/lrint.m4
@@ -0,0 +1,37 @@
+dnl @synopsis AC_C99_FUNC_LRINT
+dnl
+dnl Check whether C99's lrint function is available.
+dnl @version 1.3 Feb 12 2002
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LRINT],
+[AC_CACHE_CHECK(for lrint,
+ ac_cv_c99_lrint,
+[
+lrint_save_CFLAGS=$CFLAGS
+CFLAGS="-lm"
+AC_TRY_LINK([
+#define _ISOC9X_SOURCE 1
+#define _ISOC99_SOURCE 1
+#define __USE_ISOC99 1
+#define __USE_ISOC9X 1
+
+#include
+], if (!lrint(3.14159)) lrint(2.7183);, ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no)
+
+CFLAGS=$lrint_save_CFLAGS
+
+])
+
+if test "$ac_cv_c99_lrint" = yes; then
+ AC_DEFINE(HAVE_LRINT, 1,
+ [Define if you have C99's lrint function.])
+fi
+])# AC_C99_FUNC_LRINT
+
diff --git a/M4/lrintf.m4 b/M4/lrintf.m4
new file mode 100644
index 00000000..f921e9ed
--- /dev/null
+++ b/M4/lrintf.m4
@@ -0,0 +1,37 @@
+dnl @synopsis AC_C99_FUNC_LRINTF
+dnl
+dnl Check whether C99's lrintf function is available.
+dnl @version 1.3 Feb 12 2002
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LRINTF],
+[AC_CACHE_CHECK(for lrintf,
+ ac_cv_c99_lrintf,
+[
+lrintf_save_CFLAGS=$CFLAGS
+CFLAGS="-lm"
+AC_TRY_LINK([
+#define _ISOC9X_SOURCE 1
+#define _ISOC99_SOURCE 1
+#define __USE_ISOC99 1
+#define __USE_ISOC9X 1
+
+#include
+], if (!lrintf(3.14159)) lrintf(2.7183);, ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no)
+
+CFLAGS=$lrintf_save_CFLAGS
+
+])
+
+if test "$ac_cv_c99_lrintf" = yes; then
+ AC_DEFINE(HAVE_LRINTF, 1,
+ [Define if you have C99's lrintf function.])
+fi
+])# AC_C99_FUNC_LRINTF
+
diff --git a/M4/mkoctfile_version.m4 b/M4/mkoctfile_version.m4
new file mode 100644
index 00000000..4fdfd63d
--- /dev/null
+++ b/M4/mkoctfile_version.m4
@@ -0,0 +1,37 @@
+dnl @synopsis AC_MKOCTFILE_VERSION
+dnl
+dnl Find the version of mkoctfile.
+dnl @version 1.0 Aug 23 2007
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+dnl
+
+AC_DEFUN([AC_MKOCTFILE_VERSION],
+[
+
+
+AC_ARG_WITH(mkoctfile,
+ [ --with-mkoctfile choose the mkoctfile version], [ with_mkoctfile=$withval ])
+
+test -z "$with_mkoctfile" && with_mkoctfile=mkoctfile
+
+AC_CHECK_PROG(HAVE_MKOCTFILE,$with_mkoctfile,yes,no)
+
+if test "x$ac_cv_prog_HAVE_MKOCTFILE" = "xyes" ; then
+ MKOCTFILE=$with_mkoctfile
+
+ AC_MSG_CHECKING([for version of $MKOCTFILE])
+ MKOCTFILE_VERSION=`$with_mkoctfile --version 2>&1 | sed 's/mkoctfile, version //g'`
+ AC_MSG_RESULT($MKOCTFILE_VERSION)
+ fi
+
+AC_SUBST(MKOCTFILE)
+AC_SUBST(MKOCTFILE_VERSION)
+
+])# AC_MKOCTFILE_VERSION
+
diff --git a/M4/octave.m4 b/M4/octave.m4
new file mode 100644
index 00000000..f889723c
--- /dev/null
+++ b/M4/octave.m4
@@ -0,0 +1,156 @@
+dnl Evaluate an expression in octave
+dnl
+dnl OCTAVE_EVAL(expr,var) -> var=expr
+dnl
+dnl Stolen from octave-forge
+
+AC_DEFUN([OCTAVE_EVAL],
+[
+AC_MSG_CHECKING([for $1 in $OCTAVE])
+$2=`echo "disp($1)" | $OCTAVE -qfH`
+AC_MSG_RESULT($$2)
+AC_SUBST($2)
+]) # OCTAVE_EVAL
+
+dnl @synopsis AC_OCTAVE_VERSION
+dnl
+dnl Find the version of Octave.
+dnl @version 1.0 Aug 23 2007
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+dnl
+
+AC_DEFUN([AC_OCTAVE_VERSION],
+[
+
+AC_ARG_WITH(octave,
+ [ --with-octave choose the octave version], [ with_octave=$withval ])
+
+test -z "$with_octave" && with_octave=octave
+
+AC_CHECK_PROG(HAVE_OCTAVE,$with_octave,yes,no)
+
+if test "x$ac_cv_prog_HAVE_OCTAVE" = "xyes" ; then
+ OCTAVE=$with_octave
+ OCTAVE_EVAL(OCTAVE_VERSION,OCTAVE_VERSION)
+ fi
+
+AC_SUBST(OCTAVE)
+AC_SUBST(OCTAVE_VERSION)
+
+])# AC_OCTAVE_VERSION
+
+dnl @synopsis AC_OCTAVE_CONFIG_VERSION
+dnl
+dnl Find the version of Octave.
+dnl @version 1.0 Aug 23 2007
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+dnl
+
+AC_DEFUN([AC_OCTAVE_CONFIG_VERSION],
+[
+
+AC_ARG_WITH(octave-config,
+ [ --with-octave-config choose the octave-config version], [ with_octave_config=$withval ])
+
+test -z "$with_octave_config" && with_octave_config=octave-config
+
+AC_CHECK_PROG(HAVE_OCTAVE_CONFIG,$with_octave_config,yes,no)
+
+if test "x$ac_cv_prog_HAVE_OCTAVE_CONFIG" = "xyes" ; then
+ OCTAVE_CONFIG=$with_octave_config
+ AC_MSG_CHECKING([for version of $OCTAVE_CONFIG])
+ OCTAVE_CONFIG_VERSION=`$OCTAVE_CONFIG --version`
+ AC_MSG_RESULT($OCTAVE_CONFIG_VERSION)
+ fi
+
+AC_SUBST(OCTAVE_CONFIG)
+AC_SUBST(OCTAVE_CONFIG_VERSION)
+
+])# AC_OCTAVE_CONFIG_VERSION
+
+dnl @synopsis AC_OCTAVE_BUILD
+dnl
+dnl Check programs and headers required for building octave plugins.
+dnl @version 1.0 Aug 23 2007
+dnl @author Erik de Castro Lopo
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any
+dnl purpose is hereby granted without fee, provided that the above copyright
+dnl and this permission notice appear in all copies. No representations are
+dnl made about the suitability of this software for any purpose. It is
+dnl provided "as is" without express or implied warranty.
+
+
+AC_DEFUN([AC_OCTAVE_BUILD],
+[
+
+dnl Default to no.
+OCTAVE_BUILD=no
+
+AC_OCTAVE_VERSION
+AC_MKOCTFILE_VERSION
+AC_OCTAVE_CONFIG_VERSION
+
+prog_concat="$ac_cv_prog_HAVE_OCTAVE$ac_cv_prog_HAVE_OCTAVE_CONFIG$ac_cv_prog_HAVE_MKOCTFILE"
+
+if test "x$prog_concat" = "xyesyesyes" ; then
+ if test "x$OCTAVE_VERSION" != "x$MKOCTFILE_VERSION" ; then
+ AC_MSG_WARN([** Mismatch between versions of octave and mkoctfile. **])
+ AC_MSG_WARN([** Octave libsndfile modules will not be built. **])
+ elif test "x$OCTAVE_VERSION" != "x$OCTAVE_CONFIG_VERSION" ; then
+ AC_MSG_WARN([** Mismatch between versions of octave and octave-config. **])
+ AC_MSG_WARN([** Octave libsndfile modules will not be built. **])
+ else
+ OCTAVE_DEST_ODIR=`$OCTAVE_CONFIG --oct-site-dir | sed 's%^/usr%${prefix}%'`
+ OCTAVE_DEST_MDIR=`$OCTAVE_CONFIG --m-site-dir | sed 's%^/usr%${prefix}%'`
+
+ AC_MSG_RESULT([retrieving compile and link flags from $MKOCTFILE])
+
+ OCT_CXXFLAGS=`$MKOCTFILE -p ALL_CXXFLAGS`
+ OCT_CXXFLAGS="$OCT_CXXFLAGS `$MKOCTFILE -p FPICFLAG`"
+ OCT_LIB_DIR=`$MKOCTFILE -p LFLAGS`
+
+ dnl Pinched from mkoctfile.
+ dnl
+ dnl LINK_DEPS="$LFLAGS $OCTAVE_LIBS $LDFLAGS $BLAS_LIBS $FFTW_LIBS $LIBS $FLIBS"
+ dnl cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $ldflags $LINK_DEPS"
+
+
+ OCT_LIBS=`$MKOCTFILE -p LFLAGS`
+ OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p OCTAVE_LIBS`"
+ OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p LDFLAGS`"
+ OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p BLAS_LIBS`"
+ OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p FFTW_LIBS`"
+ OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p LIBS`"
+ OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p FLIBS`"
+
+ OCT_LIBS="`$MKOCTFILE -p DL_LDFLAGS` $OCT_LIBS"
+
+ OCTAVE_BUILD=yes
+ AC_MSG_RESULT([building octave libsndfile module... $OCTAVE_BUILD])
+ fi
+ fi
+
+
+AC_SUBST(OCTAVE_DEST_ODIR)
+AC_SUBST(OCTAVE_DEST_MDIR)
+
+AC_SUBST(OCT_CXXFLAGS)
+AC_SUBST(OCT_LIB_DIR)
+AC_SUBST(OCT_LIBS)
+
+AM_CONDITIONAL(BUILD_OCTAVE_MOD, test -n "$OCT_CXXFLAGS")
+
+])# AC_OCTAVE_BUILD
diff --git a/Makefile.am b/Makefile.am
index bae93e10..ec03728f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,11 +1,14 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = man doc Win32 Octave src examples regtest tests
-DIST_SUBDIRS = $(SUBDIRS)
-EXTRA_DIST = reconfigure.mk acinclude.m4 libsndfile.spec.in \
- sndfile.pc.in Mingw-make-dist.sh
-
-
+if BUILD_OCTAVE_MOD
+octave_dir = Octave
+endif
+
+SUBDIRS = M4 man doc Win32 src $(octave_dir) examples regtest tests
+DIST_SUBDIRS = M4 man doc Win32 src Octave examples regtest tests
+EXTRA_DIST = libsndfile.spec.in sndfile.pc.in Mingw-make-dist.sh
+
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = sndfile.pc
@@ -19,9 +22,3 @@ genfiles :
(cd tests ; make genfiles)
-## Do not edit or modify anything in this comment block.
-## The arch-tag line is a file identity tag for the GNU Arch
-## revision control system.
-##
-## arch-tag: e40c569e-8020-4e95-b774-6b0703614526
-
diff --git a/Octave/Makefile.am b/Octave/Makefile.am
index 146cd29c..7e84c6ac 100644
--- a/Octave/Makefile.am
+++ b/Octave/Makefile.am
@@ -1,14 +1,79 @@
## Process this file with automake to produce Makefile.in
-EXTRA_DIST = sndfile_load.m sndfile_save.m sndfile_play.m
+# Prevent any extension.
+EXEEXT =
+
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+
+EXTRA_DIST = sndfile_load.m sndfile_save.m sndfile_play.m \
+ octave_test.m octave_test.sh $(oct_module_srcs)
octconfigdir = $(exec_prefix)/share/octave/site/m
octconfig_DATA = sndfile_load.m sndfile_save.m sndfile_play.m
-
-## Do not edit or modify anything in this comment block.
-## The arch-tag line is a file identity tag for the GNU Arch
-## revision control system.
-##
-## arch-tag: 56f1645a-3a13-4846-acc7-8b4abf2904ff
+OCTAVE_DEST_MDIR = @OCTAVE_DEST_MDIR@
+OCTAVE_DEST_ODIR = @OCTAVE_DEST_ODIR@
+OCT_CXXFLAGS = @OCT_CXXFLAGS@
+OCT_LIB_DIR = @OCT_LIB_DIR@
+OCT_LIBS = @OCT_LIBS@
+
+SNDFILEDIR = $(top_builddir)/src
+INCLUDES = -I$(SNDFILEDIR)
+
+oct_module_srcs = sfread.cc sfwrite.cc format.cc
+oct_modules = sfread.oct sfwrite.oct
+
+# Make these noinst so they can be installed manually.
+noinst_DATA = $(oct_modules)
+
+noinst_HEADERS = format.h
+
+
+# Need to jump through extra hoops here because we only these Octave
+# modules must be dynamic. However, to make the tests pass, they need
+# to be statically linked to the libsndfile that has just been built.
+#
+# Maybe should create both dynamic and static versions and install
+# the dynamic and test the static.
+sfread.oct : format.cc sfread.cc
+ $(CXXLINK) $(OCT_CXXFLAGS) $(INCLUDES) $+ $(OCT_LIB_DIR) $(OCT_LIBS) $(SNDFILEDIR)/libsndfile.la
+
+sfwrite.oct : format.cc sfwrite.cc
+ $(CXXLINK) $(OCT_CXXFLAGS) $(INCLUDES) $+ $(OCT_LIB_DIR) $(OCT_LIBS) $(SNDFILEDIR)/libsndfile.la
+
+
+# Allow for the test being run in the build dir, but the test script
+# being located in the source dir.
+check :
+ octave_src_dir=$(srcdir) $(srcdir)/octave_test.sh
+
+
+# Since the octave modules are installed in a special location, a custom install
+# and uninstall routine must be specified.
+install-exec-local : $(oct_modules)
+ @$(NORMAL_INSTALL)
+ test -z "$(OCTAVE_DEST_ODIR)" || $(mkdir_p) "$(DESTDIR)$(OCTAVE_DEST_ODIR)"
+ @list='$(oct_modules)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL) '$$p' '$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL) "$$p" "$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-local :
+ @$(NORMAL_UNINSTALL)
+ @list='$(oct_modules)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f'"; \
+ rm -f "$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f"; \
+ done
+
+clean-local :
+ rm -f $(oct_modules)
diff --git a/Octave/Readme.txt b/Octave/Readme.txt
new file mode 100644
index 00000000..363c1c8f
--- /dev/null
+++ b/Octave/Readme.txt
@@ -0,0 +1,23 @@
+The libsndfile Modules for GNU Octave
+=====================================
+
+These modules are currently known to work with version 2.9 of GNU Octave on
+Linux. They have not been tested elsewhere.
+
+
+Build Requirements
+------------------
+
+In order to build these libsndfile related modules for GNU Octave on a Debian
+GNU/Linux (or Debian derived) system, you will need (on top of what is normally
+required to build libsndfile) the package:
+
+ octaveX.Y-headers
+
+where X.Y matches the version number of your installation of GNU Octave.
+
+The configure script in the top level libsndfile directory will detect the
+presence and correct versions of the Octave build tools. The building of these
+modules will only go ahead if everything is correct.
+
+
diff --git a/Octave/format.cc b/Octave/format.cc
new file mode 100644
index 00000000..e4ef4e47
--- /dev/null
+++ b/Octave/format.cc
@@ -0,0 +1,214 @@
+/*
+** Copyright (C) 2007 Erik de Castro Lopo
+**
+** This program 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 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 Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include
+#include
+#include
+
+#include "sndfile.h"
+
+#include "format.h"
+
+static void
+str_split (const std::string & str, const std::string & delim, std::vector & output)
+{
+ unsigned int offset = 0 ;
+ size_t delim_index = 0 ;
+
+ delim_index = str.find (delim, offset) ;
+
+ while (delim_index != std::string::npos)
+ {
+ output.push_back (str.substr(offset, delim_index - offset)) ;
+ offset += delim_index - offset + delim.length () ;
+ delim_index = str.find (delim, offset) ;
+ }
+
+ output.push_back (str.substr (offset)) ;
+} /* str_split */
+
+static int
+hash_of_str (const std::string & str)
+{
+ int hash = 0 ;
+
+ for (unsigned k = 0 ; k < str.length () ; k++)
+ hash = (hash * 3) + tolower (str [k]) ;
+
+ return hash ;
+} /* hash_of_str */
+
+static int
+major_format_of_hash (const std::string & str)
+{ int hash ;
+
+ hash = hash_of_str (str) ;
+
+ switch (hash)
+ {
+ case 0x5c8 : /* 'wav' */ return SF_FORMAT_WAV ;
+ case 0xf84 : /* 'aiff' */ return SF_FORMAT_AIFF ;
+ case 0x198 : /* 'au' */ return SF_FORMAT_AU ;
+ case 0x579 : /* 'paf' */ return SF_FORMAT_PAF ;
+ case 0x5e5 : /* 'svx' */ return SF_FORMAT_SVX ;
+ case 0x1118 : /* 'nist' */ return SF_FORMAT_NIST ;
+ case 0x5d6 : /* 'voc' */ return SF_FORMAT_VOC ;
+ case 0x324a : /* 'ircam' */ return SF_FORMAT_IRCAM ;
+ case 0x505 : /* 'w64' */ return SF_FORMAT_W64 ;
+ case 0x1078 : /* 'mat4' */ return SF_FORMAT_MAT4 ;
+ case 0x1079 : /* 'mat5' */ return SF_FORMAT_MAT5 ;
+ case 0x5b8 : /* 'pvf' */ return SF_FORMAT_PVF ;
+ case 0x1d1 : /* 'xi' */ return SF_FORMAT_XI ;
+ case 0x56f : /* 'htk' */ return SF_FORMAT_HTK ;
+ case 0x5aa : /* 'sds' */ return SF_FORMAT_SDS ;
+ case 0x53d : /* 'avr' */ return SF_FORMAT_AVR ;
+ case 0x11d0 : /* 'wavx' */ return SF_FORMAT_WAVEX ;
+ case 0x569 : /* 'sd2' */ return SF_FORMAT_SD2 ;
+ case 0x1014 : /* 'flac' */ return SF_FORMAT_FLAC ;
+ case 0x504 : /* 'caf' */ return SF_FORMAT_CAF ;
+ case 0x5f6 : /* 'wve' */ return SF_FORMAT_WVE ;
+ default : break ;
+ } ;
+
+ printf ("%s : hash '%s' -> 0x%x\n", __func__, str.c_str (), hash) ;
+
+ return 0 ;
+} /* major_format_of_hash */
+
+static int
+minor_format_of_hash (const std::string & str)
+{ int hash ;
+
+ hash = hash_of_str (str) ;
+
+ switch (hash)
+ {
+ case 0x1085 : /* 'int8' */ return SF_FORMAT_PCM_S8 ;
+ case 0x358a : /* 'uint8' */ return SF_FORMAT_PCM_U8 ;
+ case 0x31b0 : /* 'int16' */ return SF_FORMAT_PCM_16 ;
+ case 0x31b1 : /* 'int24' */ return SF_FORMAT_PCM_24 ;
+ case 0x31b2 : /* 'int32' */ return SF_FORMAT_PCM_32 ;
+ case 0x3128 : /* 'float' */ return SF_FORMAT_FLOAT ;
+ case 0x937d : /* 'double' */ return SF_FORMAT_DOUBLE ;
+ case 0x11bd : /* 'ulaw' */ return SF_FORMAT_ULAW ;
+ case 0xfa1 : /* 'alaw' */ return SF_FORMAT_ALAW ;
+ case 0xfc361 : /* 'ima_adpcm' */ return SF_FORMAT_IMA_ADPCM ;
+ case 0x5739a : /* 'ms_adpcm' */ return SF_FORMAT_MS_ADPCM ;
+ case 0x9450 : /* 'gsm610' */ return SF_FORMAT_GSM610 ;
+ case 0x172a3 : /* 'g721_32' */ return SF_FORMAT_G721_32 ;
+ case 0x172d8 : /* 'g723_24' */ return SF_FORMAT_G723_24 ;
+ case 0x172da : /* 'g723_40' */ return SF_FORMAT_G723_40 ;
+ default : break ;
+ } ;
+
+ printf ("%s : hash '%s' -> 0x%x\n", __func__, str.c_str (), hash) ;
+
+ return 0 ;
+} /* minor_format_of_hash */
+
+
+int
+format_of_str (const std::string & fmt)
+{
+ std::vector split ;
+
+ str_split (fmt, "-", split) ;
+
+ if (split.size () != 2)
+ return 0 ;
+
+ int major_fmt = major_format_of_hash (split.at (0)) ;
+ if (major_fmt == 0)
+ return 0 ;
+
+ int minor_fmt = minor_format_of_hash (split.at (1)) ;
+ if (minor_fmt == 0)
+ return 0 ;
+
+ return major_fmt | minor_fmt ;
+} /* format_of_str */
+
+static const char *
+string_of_major_format (int format)
+{
+ switch (format & SF_FORMAT_TYPEMASK)
+ {
+ case SF_FORMAT_WAV : return "wav" ;
+ case SF_FORMAT_AIFF : return "aiff" ;
+ case SF_FORMAT_AU : return "au" ;
+ case SF_FORMAT_PAF : return "paf" ;
+ case SF_FORMAT_SVX : return "svx" ;
+ case SF_FORMAT_NIST : return "nist" ;
+ case SF_FORMAT_VOC : return "voc" ;
+ case SF_FORMAT_IRCAM : return "ircam" ;
+ case SF_FORMAT_W64 : return "w64" ;
+ case SF_FORMAT_MAT4 : return "mat4" ;
+ case SF_FORMAT_MAT5 : return "mat5" ;
+ case SF_FORMAT_PVF : return "pvf" ;
+ case SF_FORMAT_XI : return "xi" ;
+ case SF_FORMAT_HTK : return "htk" ;
+ case SF_FORMAT_SDS : return "sds" ;
+ case SF_FORMAT_AVR : return "avr" ;
+ case SF_FORMAT_WAVEX : return "wavx" ;
+ case SF_FORMAT_SD2 : return "sd2" ;
+ case SF_FORMAT_FLAC : return "flac" ;
+ case SF_FORMAT_CAF : return "caf" ;
+ case SF_FORMAT_WVE : return "wfe" ;
+ default : break ;
+ } ;
+
+ return "unknown" ;
+} /* string_of_major_format */
+
+static const char *
+string_of_minor_format (int format)
+{
+ switch (format & SF_FORMAT_SUBMASK)
+ {
+ case SF_FORMAT_PCM_S8 : return "int8" ;
+ case SF_FORMAT_PCM_U8 : return "uint8" ;
+ case SF_FORMAT_PCM_16 : return "int16" ;
+ case SF_FORMAT_PCM_24 : return "int24" ;
+ case SF_FORMAT_PCM_32 : return "int32" ;
+ case SF_FORMAT_FLOAT : return "float" ;
+ case SF_FORMAT_DOUBLE : return "double" ;
+ case SF_FORMAT_ULAW : return "ulaw" ;
+ case SF_FORMAT_ALAW : return "alaw" ;
+ case SF_FORMAT_IMA_ADPCM : return "ima_adpcm" ;
+ case SF_FORMAT_MS_ADPCM : return "ms_adpcm" ;
+ case SF_FORMAT_GSM610 : return "gsm610" ;
+ case SF_FORMAT_G721_32 : return "g721_32" ;
+ case SF_FORMAT_G723_24 : return "g723_24" ;
+ case SF_FORMAT_G723_40 : return "g723_40" ;
+ default : break ;
+ } ;
+
+ return "unknown" ;
+} /* string_of_minor_format */
+
+void
+string_of_format (std::string & fmt, int format)
+{
+ char buffer [64] ;
+
+ snprintf (buffer, sizeof (buffer), "%s-%s", string_of_major_format (format), string_of_minor_format (format)) ;
+
+ fmt = buffer ;
+
+ return ;
+} /* string_of_format */
diff --git a/Octave/format.h b/Octave/format.h
new file mode 100644
index 00000000..18843cee
--- /dev/null
+++ b/Octave/format.h
@@ -0,0 +1,21 @@
+/*
+** Copyright (C) 2007 Erik de Castro Lopo
+**
+** This program 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 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 Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+int format_of_str (const std::string & fmt) ;
+
+void string_of_format (std::string & fmt, int format) ;
diff --git a/Octave/octave_test.m b/Octave/octave_test.m
new file mode 100644
index 00000000..30b60139
--- /dev/null
+++ b/Octave/octave_test.m
@@ -0,0 +1,56 @@
+# Copyright (C) 2007 Erik de Castro Lopo
+#
+# This program 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 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# These tests are nowhere near comprehensive.
+
+printf ("\n\n\n\n\n\n\n") ;
+
+printf (" Running Octave tests : ") ;
+fflush (stdout) ;
+
+filename = "whatever" ;
+srate_out = 32000 ;
+fmt_out = "wav-float" ;
+
+t = (2 * pi / srate_out * (0:srate_out-1))' ;
+data_out = sin (440.0 * t) ;
+
+# Write out a file.
+sfwrite (filename, data_out, srate_out, fmt_out) ;
+
+# Read it back in again.
+[ data_in, srate_in, fmt_in ] = sfread (filename) ;
+
+if (srate_in != srate_out)
+ error ("\n\nSample rate mismatch : %d -> %d.\n\n", srate_out, srate_in) ;
+ endif
+
+# Octave strcmp return 1 for the same.
+if (strcmp (fmt_in, fmt_out) != 1)
+ error ("\n\nFormat error : '%s' -> '%s'.\n\n", fmt_out, fmt_in) ;
+ endif
+
+err = max (abs (data_out - data_in)) ;
+
+if (err > 1e-7)
+ error ("err : %g\n", err) ;
+ endif
+
+printf ("ok") ;
+
+printf ("\n\n\n\n\n\n\n") ;
+
+unlink (filename) ;
diff --git a/Octave/octave_test.sh b/Octave/octave_test.sh
new file mode 100755
index 00000000..419b5969
--- /dev/null
+++ b/Octave/octave_test.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+
+# Check where we're being run from.
+if [ -d Octave ]; then
+ cd Octave
+ fi
+
+# Find libsndfile shared object.
+libsndfile_lib_location=""
+
+if [ -f "../src/.libs/libsndfile.so" ]; then
+ libsndfile_lib_location="../src/.libs/"
+elif [ -f "../src/libsndfile.so" ]; then
+ libsndfile_lib_location="../src/"
+elif [ -f "../src/.libs/libsndfile.dylib" ]; then
+ libsndfile_lib_location="../src/.libs/"
+elif [ -f "../src/libsndfile.dylib" ]; then
+ libsndfile_lib_location="../src/"
+else
+ echo "Not able to find the libsndfile shared lib we've just built."
+ exit 1
+ fi
+libsndfile_lib_location=`(cd $libsndfile_lib_location && pwd)`
+
+
+# Find sfread.oct and sfwrite.oct
+sfread_write_oct_location=""
+
+if [ -f .libs/sfread.oct ]; then
+ sfread_write_oct_location=".libs"
+elif [ -f sfread.oct ]; then
+ sfread_write_oct_location="."
+else
+ echo "Not able to find the sfread.oct/sfwrite.oct binaries we've just built."
+ exit 1
+ fi
+
+case `file -b $sfread_write_oct_location/sfread.oct` in
+ ELF*)
+ ;;
+ Mach*)
+ echo "Tests don't work on this platform."
+ exit 0
+ ;;
+ *)
+ echo "Not able to find the sfread.oct/sfwrite.oct binaries we've just built."
+ exit 1
+ ;;
+ esac
+
+# echo "libsndfile_lib_location : $libsndfile_lib_location"
+# echo "sfread_write_oct_location : $sfread_write_oct_location"
+
+LD_LIBRARY_PATH="$libsndfile_lib_location:$LD_LIBRARY_PATH"
+
+octave_src_dir=`(cd $octave_src_dir && pwd)`
+
+octave_script="$octave_src_dir/octave_test.m"
+
+(cd $sfread_write_oct_location && octave -qH $octave_script)
+
+
diff --git a/Octave/sfread.cc b/Octave/sfread.cc
new file mode 100644
index 00000000..4fd17717
--- /dev/null
+++ b/Octave/sfread.cc
@@ -0,0 +1,103 @@
+/*
+** Copyright (C) 2007 Erik de Castro Lopo
+**
+** This program 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 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 Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include
+
+#include "sndfile.h"
+
+#include "format.h"
+
+#define FOUR_GIG (0x100000000LL)
+#define BUFFER_FRAMES 8192
+
+DEFUN_DLD (sfread, args, nargout , "\
+-*- texinfo -*-\n\
+@deftypefn {Function File} {@var{I},@var{srate},@var{format} =} sfread (@var{filename})\n\
+Read a sound file from disk using libsndfile.\n\
+\n\
+@seealso{wavread}\n\
+@end deftypefn\n\
+")
+{ SNDFILE * file ;
+ SF_INFO sfinfo ;
+
+ octave_value_list retval ;
+
+ int nargin = args.length () ;
+
+ /* Bail out if the input parameters are bad. */
+ if ((nargin != 1) || !args (0) .is_string () || nargout < 1 || nargout > 3)
+ { print_usage () ;
+ return retval ;
+ } ;
+
+ memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+ std::string filename = args (0).string_value () ;
+
+ if ((file = sf_open (filename.c_str (), SFM_READ, &sfinfo)) == NULL)
+ { error ("sfread: couldn't open file %s : %s", filename.c_str (), sf_strerror (NULL)) ;
+ return retval ;
+ } ;
+
+ if (sfinfo.frames > FOUR_GIG)
+ printf ("This is a really huge file (%lld frames).\nYou may run out of memory trying to load it.\n", (long long) sfinfo.frames) ;
+
+ dim_vector dim = dim_vector () ;
+ dim.resize (2) ;
+ dim (0) = sfinfo.frames ;
+ dim (1) = sfinfo.channels ;
+
+ /* Should I be using Matrix instead? */
+ NDArray out (dim, 0.0) ;
+
+ float buffer [BUFFER_FRAMES * sfinfo.channels] ;
+ int readcount ;
+ sf_count_t total = 0 ;
+
+ do
+ { readcount = sf_readf_float (file, buffer, BUFFER_FRAMES) ;
+
+ /* Make sure we don't read more frames than we allocated. */
+ if (total + readcount > sfinfo.frames)
+ readcount = sfinfo.frames - total ;
+
+ for (int ch = 0 ; ch < sfinfo.channels ; ch++)
+ { for (int k = 0 ; k < readcount ; k++)
+ out (total + k, ch) = buffer [k * sfinfo.channels + ch] ;
+ } ;
+
+ total += readcount ;
+ } while (readcount > 0 && total < sfinfo.frames) ;
+
+ retval.append (out.squeeze ()) ;
+
+ if (nargout >= 2)
+ retval.append ((octave_uint32) sfinfo.samplerate) ;
+
+ if (nargout >= 3)
+ { std::string fmt ("") ;
+ string_of_format (fmt, sfinfo.format) ;
+ retval.append (fmt) ;
+ } ;
+
+ /* Clean up. */
+ sf_close (file) ;
+
+ return retval ;
+} /* sfread */
diff --git a/Octave/sfwrite.cc b/Octave/sfwrite.cc
new file mode 100644
index 00000000..e6b04404
--- /dev/null
+++ b/Octave/sfwrite.cc
@@ -0,0 +1,112 @@
+/*
+** Copyright (C) 2007 Erik de Castro Lopo
+**
+** This program 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 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 Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include
+
+#include "sndfile.h"
+
+#include "format.h"
+
+#define FOUR_GIG (0x100000000LL)
+#define BUFFER_FRAMES 8192
+
+DEFUN_DLD (sfwrite, args, nargout , "\
+-*- texinfo -*-\n\
+@deftypefn {Function File} sfwrite (@var{filename},@var{data},@var{srate},@var{format})\n\
+Write a sound file to disk using libsndfile.\n\
+\n\
+@seealso{wavwrite}\n\
+@end deftypefn\n\
+")
+{ SNDFILE * file ;
+ SF_INFO sfinfo ;
+
+ octave_value_list retval ;
+
+ int nargin = args.length () ;
+
+ /* Bail out if the input parameters are bad. */
+ if (nargin != 4 || !args (0).is_string () || !args (1).is_real_matrix ()
+ || !args (2).is_real_scalar () || !args (3).is_string ()
+ || nargout != 0)
+ { print_usage () ;
+ return retval ;
+ } ;
+
+ std::string filename = args (0).string_value () ;
+ std::string format = args (3).string_value () ;
+
+ memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+ sfinfo.format = format_of_str (format) ;
+ if (sfinfo.format == 0)
+ { error ("Bad format '%s'", format.c_str ()) ;
+ return retval ;
+ } ;
+
+ sfinfo.samplerate = lrint (args (2).scalar_value ()) ;
+ if (sfinfo.samplerate < 1)
+ { error ("Bad sample rate : %d.\n", sfinfo.samplerate) ;
+ return retval ;
+ } ;
+
+ Matrix data = args (1).matrix_value () ;
+ long rows = args (1).rows () ;
+ long cols = args (1).columns () ;
+
+ if (cols > rows)
+ { error ("Audio data should have one column per channel, but supplied data "
+ "has %ld rows and %ld columns.\n", rows, cols) ;
+ return retval ;
+ } ;
+
+ sfinfo.channels = cols ;
+
+ if ((file = sf_open (filename.c_str (), SFM_WRITE, &sfinfo)) == NULL)
+ { error ("Couldn't open file %s : %s", filename.c_str (), sf_strerror (NULL)) ;
+ return retval ;
+ } ;
+
+ float buffer [BUFFER_FRAMES * sfinfo.channels] ;
+ int writecount ;
+ long total = 0 ;
+
+ do
+ {
+ writecount = BUFFER_FRAMES ;
+
+ /* Make sure we don't read more frames than we allocated. */
+ if (total + writecount > rows)
+ writecount = rows - total ;
+
+ for (int ch = 0 ; ch < sfinfo.channels ; ch++)
+ { for (int k = 0 ; k < writecount ; k++)
+ buffer [k * sfinfo.channels + ch] = data (total + k, ch) ;
+ } ;
+
+ if (writecount > 0)
+ sf_writef_float (file, buffer, writecount) ;
+
+ total += writecount ;
+ } while (writecount > 0 && total < rows) ;
+
+ /* Clean up. */
+ sf_close (file) ;
+
+ return retval ;
+} /* sfwrite */
diff --git a/acinclude.m4 b/acinclude.m4
deleted file mode 100644
index 33d91294..00000000
--- a/acinclude.m4
+++ /dev/null
@@ -1,569 +0,0 @@
-dnl By default, many hosts won't let programs access large files;
-dnl one must use special compiler options to get large-file access to work.
-dnl For more details about this brain damage please see:
-dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
-
-dnl Written by Paul Eggert .
-
-dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
-dnl AC_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME)
-AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_FLAGS],
- [AC_CACHE_CHECK([for $1 value to request large file support],
- ac_cv_sys_largefile_$1,
- [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || {
- ac_cv_sys_largefile_$1=no
- ifelse($1, CFLAGS,
- [case "$host_os" in
- # IRIX 6.2 and later require cc -n32.
-changequote(, )dnl
- irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*)
-changequote([, ])dnl
- if test "$GCC" != yes; then
- ac_cv_sys_largefile_CFLAGS=-n32
- fi
- ac_save_CC="$CC"
- CC="$CC $ac_cv_sys_largefile_CFLAGS"
- AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no)
- CC="$ac_save_CC"
- esac])
- }])])
-
-dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
-dnl AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(VAR, VAL)
-AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND],
- [case $2 in
- no) ;;
- ?*)
- case "[$]$1" in
- '') $1=$2 ;;
- *) $1=[$]$1' '$2 ;;
- esac ;;
- esac])
-
-dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
-dnl AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT)
-AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE],
- [AC_CACHE_CHECK([for $1], $2,
- [$2=no
-changequote(, )dnl
- $4
- for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
- case "$ac_flag" in
- -D$1)
- $2=1 ;;
- -D$1=*)
- $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
- esac
- done
-changequote([, ])dnl
- ])
- if test "[$]$2" != no; then
- AC_DEFINE_UNQUOTED([$1], [$]$2, [$3])
- fi])
-
-AC_DEFUN([AC_SYS_EXTRA_LARGEFILE],
- [AC_REQUIRE([AC_CANONICAL_HOST])
- AC_ARG_ENABLE(largefile,
- [ --disable-largefile omit support for large files])
- if test "$enable_largefile" != no; then
- AC_CHECK_TOOL(GETCONF, getconf)
- AC_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS)
- AC_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS)
- AC_SYS_EXTRA_LARGEFILE_FLAGS(LIBS)
-
- for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
- case "$ac_flag" in
- no) ;;
- -D_FILE_OFFSET_BITS=*) ;;
- -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;;
- -D_LARGE_FILES | -D_LARGE_FILES=*) ;;
- -D?* | -I?*)
- AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;;
- *)
- AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;;
- esac
- done
- AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS")
- AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS")
- AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS,
- ac_cv_sys_file_offset_bits,
- [Number of bits in a file offset, on hosts where this is settable.])
- [case "$host_os" in
- # HP-UX 10.20 and later
- hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
- ac_cv_sys_file_offset_bits=64 ;;
- esac]
- AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE,
- ac_cv_sys_largefile_source,
- [Define to make fseeko etc. visible, on some hosts.],
- [case "$host_os" in
- # HP-UX 10.20 and later
- hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
- ac_cv_sys_largefile_source=1 ;;
- esac])
- AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGE_FILES,
- ac_cv_sys_large_files,
- [Define for large files, on AIX-style hosts.],
- [case "$host_os" in
- # AIX 4.2 and later
- aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*)
- ac_cv_sys_large_files=1 ;;
- esac])
- fi
- ])
-
-
-
-
-
-
-dnl @synopsis AC_C_FIND_ENDIAN
-dnl
-dnl Determine endian-ness of target processor.
-dnl @version 1.1 Mar 03 2002
-dnl @author Erik de Castro Lopo
-dnl
-dnl Majority written from scratch to replace the standard autoconf macro
-dnl AC_C_BIGENDIAN. Only part remaining from the original it the invocation
-dnl of the AC_TRY_RUN macro.
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this file for any
-dnl purpose is hereby granted without fee, provided that the above copyright
-dnl and this permission notice appear in all copies. No representations are
-dnl made about the suitability of this software for any purpose. It is
-dnl provided "as is" without express or implied warranty.
-
-dnl Find endian-ness in the following way:
-dnl 1) Look in .
-dnl 2) If 1) fails, look in and .
-dnl 3) If 1) and 2) fails and not cross compiling run a test program.
-dnl 4) If 1) and 2) fails and cross compiling then guess based on target.
-
-AC_DEFUN([AC_C_FIND_ENDIAN],
-[AC_CACHE_CHECK(processor byte ordering,
- ac_cv_c_byte_order,
-
-# Initialize to unknown
-ac_cv_c_byte_order=unknown
-
-if test x$ac_cv_header_endian_h = xyes ; then
-
- # First try which should set BYTE_ORDER.
-
- [AC_TRY_LINK([
- #include
- #if BYTE_ORDER != LITTLE_ENDIAN
- not big endian
- #endif
- ], return 0 ;,
- ac_cv_c_byte_order=little
- )]
-
- [AC_TRY_LINK([
- #include
- #if BYTE_ORDER != BIG_ENDIAN
- not big endian
- #endif
- ], return 0 ;,
- ac_cv_c_byte_order=big
- )]
-
- fi
-
-if test $ac_cv_c_byte_order = unknown ; then
-
- [AC_TRY_LINK([
- #include
- #include
- #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
- #endif
- ], return 0 ;,
-
- [AC_TRY_LINK([
- #include
- #include
- #if BYTE_ORDER != LITTLE_ENDIAN
- not big endian
- #endif
- ], return 0 ;,
- ac_cv_c_byte_order=little
- )]
-
- [AC_TRY_LINK([
- #include
- #include
- #if BYTE_ORDER != LITTLE_ENDIAN
- not big endian
- #endif
- ], return 0 ;,
- ac_cv_c_byte_order=little
- )]
-
- )]
-
- fi
-
-if test $ac_cv_c_byte_order = unknown ; then
- if test $cross_compiling = yes ; then
- # This is the last resort. Try to guess the target processor endian-ness
- # by looking at the target CPU type.
- [
- case "$target_cpu" in
- alpha* | i?86* | mipsel* | ia64*)
- ac_cv_c_big_endian=0
- ac_cv_c_little_endian=1
- ;;
-
- m68* | mips* | powerpc* | hppa* | sparc*)
- ac_cv_c_big_endian=1
- ac_cv_c_little_endian=0
- ;;
-
- esac
- ]
- else
- AC_TRY_RUN(
- [[
- int main (void)
- { /* Are we little or big endian? From Harbison&Steele. */
- union
- { long l ;
- char c [sizeof (long)] ;
- } u ;
- u.l = 1 ;
- return (u.c [sizeof (long) - 1] == 1);
- }
- ]], , ac_cv_c_byte_order=big,
- ac_cv_c_byte_order=unknown
- )
-
- AC_TRY_RUN(
- [[int main (void)
- { /* Are we little or big endian? From Harbison&Steele. */
- union
- { long l ;
- char c [sizeof (long)] ;
- } u ;
- u.l = 1 ;
- return (u.c [0] == 1);
- }]], , ac_cv_c_byte_order=little,
- ac_cv_c_byte_order=unknown
- )
- fi
- fi
-
-)
-]
-
-if test $ac_cv_c_byte_order = big ; then
- ac_cv_c_big_endian=1
- ac_cv_c_little_endian=0
-elif test $ac_cv_c_byte_order = little ; then
- ac_cv_c_big_endian=0
- ac_cv_c_little_endian=1
-else
- ac_cv_c_big_endian=0
- ac_cv_c_little_endian=0
-
- AC_MSG_WARN([[*****************************************************************]])
- AC_MSG_WARN([[*** Not able to determine endian-ness of target processor. ]])
- AC_MSG_WARN([[*** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in ]])
- AC_MSG_WARN([[*** src/config.h may need to be hand editied. ]])
- AC_MSG_WARN([[*****************************************************************]])
- fi
-
-)# AC_C_FIND_ENDIAN
-
-
-
-
-
-dnl @synopsis AC_C99_FLEXIBLE_ARRAY
-dnl
-dnl Dose the compiler support the 1999 ISO C Standard "stuct hack".
-dnl @version 1.1 Mar 15 2004
-dnl @author Erik de Castro Lopo
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this file for any
-dnl purpose is hereby granted without fee, provided that the above copyright
-dnl and this permission notice appear in all copies. No representations are
-dnl made about the suitability of this software for any purpose. It is
-dnl provided "as is" without express or implied warranty.
-
-AC_DEFUN([AC_C99_FLEXIBLE_ARRAY],
-[AC_CACHE_CHECK(C99 struct flexible array support,
- ac_cv_c99_flexible_array,
-
-# Initialize to unknown
-ac_cv_c99_flexible_array=no
-
-AC_TRY_LINK([[
- #include
- typedef struct {
- int k;
- char buffer [] ;
- } MY_STRUCT ;
- ]],
- [ MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42); ],
- ac_cv_c99_flexible_array=yes,
- ac_cv_c99_flexible_array=no
- ))]
-) # AC_C99_FLEXIBLE_ARRAY
-
-
-
-
-
-dnl @synopsis AC_C99_FUNC_LRINT
-dnl
-dnl Check whether C99's lrint function is available.
-dnl @version 1.3 Feb 12 2002
-dnl @author Erik de Castro Lopo
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this file for any
-dnl purpose is hereby granted without fee, provided that the above copyright
-dnl and this permission notice appear in all copies. No representations are
-dnl made about the suitability of this software for any purpose. It is
-dnl provided "as is" without express or implied warranty.
-dnl
-AC_DEFUN([AC_C99_FUNC_LRINT],
-[AC_CACHE_CHECK(for lrint,
- ac_cv_c99_lrint,
-[
-lrint_save_CFLAGS=$CFLAGS
-CFLAGS="-lm"
-AC_TRY_LINK([
-#define _ISOC9X_SOURCE 1
-#define _ISOC99_SOURCE 1
-#define __USE_ISOC99 1
-#define __USE_ISOC9X 1
-
-#include
-], if (!lrint(3.14159)) lrint(2.7183);, ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no)
-
-CFLAGS=$lrint_save_CFLAGS
-
-])
-
-if test "$ac_cv_c99_lrint" = yes; then
- AC_DEFINE(HAVE_LRINT, 1,
- [Define if you have C99's lrint function.])
-fi
-])# AC_C99_FUNC_LRINT
-dnl @synopsis AC_C99_FUNC_LRINTF
-dnl
-dnl Check whether C99's lrintf function is available.
-dnl @version 1.3 Feb 12 2002
-dnl @author Erik de Castro Lopo
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this file for any
-dnl purpose is hereby granted without fee, provided that the above copyright
-dnl and this permission notice appear in all copies. No representations are
-dnl made about the suitability of this software for any purpose. It is
-dnl provided "as is" without express or implied warranty.
-dnl
-AC_DEFUN([AC_C99_FUNC_LRINTF],
-[AC_CACHE_CHECK(for lrintf,
- ac_cv_c99_lrintf,
-[
-AC_TRY_LINK([
-#define _ISOC9X_SOURCE 1
-#define _ISOC99_SOURCE 1
-#define __USE_ISOC99 1
-#define __USE_ISOC9X 1
-
-#include
-], if (!lrintf(3.14159)) lrintf(2.7183);, ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no)
-])
-
-if test "$ac_cv_c99_lrintf" = yes; then
- AC_DEFINE(HAVE_LRINTF, 1,
- [Define if you have C99's lrintf function.])
-fi
-])# AC_C99_FUNC_LRINTF
-
-
-
-
-dnl @synopsis AC_C99_FUNC_LLRINT
-dnl
-dnl Check whether C99's llrint function is available.
-dnl @version 1.1 Sep 30 2002
-dnl @author Erik de Castro Lopo
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this file for any
-dnl purpose is hereby granted without fee, provided that the above copyright
-dnl and this permission notice appear in all copies. No representations are
-dnl made about the suitability of this software for any purpose. It is
-dnl provided "as is" without express or implied warranty.
-dnl
-AC_DEFUN([AC_C99_FUNC_LLRINT],
-[AC_CACHE_CHECK(for llrint,
- ac_cv_c99_llrint,
-[
-AC_TRY_LINK([
-#define _ISOC9X_SOURCE 1
-#define _ISOC99_SOURCE 1
-#define __USE_ISOC99 1
-#define __USE_ISOC9X 1
-
-#include
-#include
-], int64_t x ; x = llrint(3.14159) ;, ac_cv_c99_llrint=yes, ac_cv_c99_llrint=no)
-])
-
-if test "$ac_cv_c99_llrint" = yes; then
- AC_DEFINE(HAVE_LLRINT, 1,
- [Define if you have C99's llrint function.])
-fi
-])# AC_C99_FUNC_LLRINT
-
-
-
-dnl @synopsis AC_C_CLIP_MODE
-dnl
-dnl Determine the clipping mode when converting float to int.
-dnl @version 1.0 May 17 2003
-dnl @author Erik de Castro Lopo
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this file for any
-dnl purpose is hereby granted without fee, provided that the above copyright
-dnl and this permission notice appear in all copies. No representations are
-dnl made about the suitability of this software for any purpose. It is
-dnl provided "as is" without express or implied warranty.
-
-
-
-dnl Find the clipping mode in the following way:
-dnl 1) If we are not cross compiling test it.
-dnl 2) IF we are cross compiling, assume that clipping isn't done correctly.
-
-AC_DEFUN([AC_C_CLIP_MODE],
-[AC_CACHE_CHECK(processor clipping capabilities,
- ac_cv_c_clip_type,
-
-# Initialize to unknown
-ac_cv_c_clip_positive=unknown
-ac_cv_c_clip_negative=unknown
-
-if test $ac_cv_c_clip_positive = unknown ; then
- AC_TRY_RUN(
- [[
- #define _ISOC9X_SOURCE 1
- #define _ISOC99_SOURCE 1
- #define __USE_ISOC99 1
- #define __USE_ISOC9X 1
- #include
- int main (void)
- { double fval ;
- int k, ival ;
-
- fval = 1.0 * 0x7FFFFFFF ;
- for (k = 0 ; k < 100 ; k++)
- { ival = (lrint (fval)) >> 24 ;
- if (ival != 127)
- return 1 ;
-
- fval *= 1.2499999 ;
- } ;
-
- return 0 ;
- }
- ]],
- ac_cv_c_clip_positive=yes,
- ac_cv_c_clip_positive=no,
- ac_cv_c_clip_positive=unknown
- )
-
- AC_TRY_RUN(
- [[
- #define _ISOC9X_SOURCE 1
- #define _ISOC99_SOURCE 1
- #define __USE_ISOC99 1
- #define __USE_ISOC9X 1
- #include
- int main (void)
- { double fval ;
- int k, ival ;
-
- fval = -8.0 * 0x10000000 ;
- for (k = 0 ; k < 100 ; k++)
- { ival = (lrint (fval)) >> 24 ;
- if (ival != -128)
- return 1 ;
-
- fval *= 1.2499999 ;
- } ;
-
- return 0 ;
- }
- ]],
- ac_cv_c_clip_negative=yes,
- ac_cv_c_clip_negative=no,
- ac_cv_c_clip_negative=unknown
- )
- fi
-
-if test $ac_cv_c_clip_positive = yes ; then
- ac_cv_c_clip_positive=1
-else
- ac_cv_c_clip_positive=0
- fi
-
-if test $ac_cv_c_clip_negative = yes ; then
- ac_cv_c_clip_negative=1
-else
- ac_cv_c_clip_negative=0
- fi
-
-[[
-case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in
- "00")
- ac_cv_c_clip_type="none"
- ;;
- "10")
- ac_cv_c_clip_type="positive"
- ;;
- "01")
- ac_cv_c_clip_type="negative"
- ;;
- "11")
- ac_cv_c_clip_type="both"
- ;;
- esac
- ]]
-
-)
-]
-
-)# AC_C_CLIP_MODE
-
-
-dnl @synopsis AC_ADD_CFLAGS
-dnl
-dnl Add the given option to CFLAGS, if it doesn't break the compiler
-
-AC_DEFUN([AC_ADD_CFLAGS],
-[AC_MSG_CHECKING([if $CC accepts $1])
- ac_add_cflags__old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS $1"
- AC_TRY_LINK([#include ],
- [printf("Hello, World!\n"); return 0;],
- AC_MSG_RESULT([yes]),
- AC_MSG_RESULT([no])
- CFLAGS="$ac_add_cflags__old_cflags")
-])
-
-
-
-
-ifelse(dnl
-
- Do not edit or modify anything in this comment block.
- The arch-tag line is a file identity tag for the GNU Arch
- revision control system.
-
- arch-tag: bc38294d-bb5c-42ad-90b9-779def5eaab7
-
-)dnl
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 00000000..3b64b21e
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,132 @@
+#!/bin/sh
+# Run this to set up the build system: configure, makefiles, etc.
+# (based on the version in enlightenment's cvs)
+
+ACLOCAL_FLAGS="-I M4"
+
+package="libsndfile"
+
+olddir=`pwd`
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+cd "$srcdir"
+DIE=0
+
+echo "checking for autoconf... "
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile $package."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/"
+VERSIONMKMAJ="sed -e s/\([0-9][0-9]*\)[^0-9].*/\\1/"
+VERSIONMKMIN="sed -e s/.*[0-9][0-9]*\.//"
+
+# do we need automake?
+if test -r Makefile.am; then
+ AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am`
+ AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP`
+ if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then
+ AM_NEEDED=""
+ fi
+ if test -z $AM_NEEDED; then
+ echo -n "checking for automake... "
+ AUTOMAKE=automake
+ ACLOCAL=aclocal
+ if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then
+ echo "yes"
+ else
+ echo "no"
+ AUTOMAKE=
+ fi
+ else
+ echo -n "checking for automake $AM_NEEDED or later... "
+ majneeded=`echo $AM_NEEDED | $VERSIONMKMAJ`
+ minneeded=`echo $AM_NEEDED | $VERSIONMKMIN`
+ for am in automake-$AM_NEEDED automake$AM_NEEDED \
+ automake automake-1.7 automake-1.8 automake-1.9 automake-1.10; do
+ ($am --version < /dev/null > /dev/null 2>&1) || continue
+ ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP`
+ maj=`echo $ver | $VERSIONMKMAJ`
+ min=`echo $ver | $VERSIONMKMIN`
+ if test $maj -eq $majneeded -a $min -ge $minneeded; then
+ AUTOMAKE=$am
+ echo $AUTOMAKE
+ break
+ fi
+ done
+ test -z $AUTOMAKE && echo "no"
+ echo -n "checking for aclocal $AM_NEEDED or later... "
+ for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED \
+ aclocal aclocal-1.7 aclocal-1.8 aclocal-1.9 aclocal-1.10; do
+ ($ac --version < /dev/null > /dev/null 2>&1) || continue
+ ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP`
+ maj=`echo $ver | $VERSIONMKMAJ`
+ min=`echo $ver | $VERSIONMKMIN`
+ if test $maj -eq $majneeded -a $min -ge $minneeded; then
+ ACLOCAL=$ac
+ echo $ACLOCAL
+ break
+ fi
+ done
+ test -z $ACLOCAL && echo "no"
+ fi
+ test -z $AUTOMAKE || test -z $ACLOCAL && {
+ echo
+ echo "You must have automake installed to compile $package."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ exit 1
+ }
+fi
+
+echo -n "checking for libtool... "
+for LIBTOOLIZE in libtoolize glibtoolize nope; do
+ ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break
+done
+if test x$LIBTOOLIZE = xnope; then
+ echo "nope."
+ LIBTOOLIZE=libtoolize
+else
+ echo $LIBTOOLIZE
+fi
+($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have libtool installed to compile $package."
+ echo "Download the appropriate package for your system,"
+ echo "or get the source from one of the GNU ftp sites"
+ echo "listed in http://www.gnu.org/order/ftp.html"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "I am going to run ./configure with no arguments - if you wish "
+ echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+echo "Generating configuration files for $package, please wait...."
+
+echo " $ACLOCAL $ACLOCAL_FLAGS"
+$ACLOCAL $ACLOCAL_FLAGS || exit 1
+echo " $LIBTOOLIZE --automake"
+$LIBTOOLIZE --automake || exit 1
+echo " autoheader"
+autoheader || exit 1
+echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
+$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
+echo " autoconf"
+autoconf || exit 1
+
+cd $olddir
+$srcdir/configure --enable-maintainer-mode --enable-gcc-werror "$@" && echo
+
+(cd src && make genfiles)
+(cd tests && make genfiles)
diff --git a/configure.ac b/configure.ac
index 2ab0aecd..8e4c235a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,13 +3,20 @@
dnl Require autoconf version
AC_PREREQ(2.57)
-AC_INIT([libsndfile],[1.0.18pre13],[erikd@mega-nerd.com])
+AC_INIT([libsndfile],[1.0.18pre17],[erikd@mega-nerd.com])
+
+# Put config stuff in Cfg.
+AC_CONFIG_AUX_DIR(Cfg)
+
AC_CONFIG_SRCDIR([src/sndfile.c])
AC_CANONICAL_TARGET([])
AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION)
AC_CONFIG_HEADERS([src/config.h])
+dnl Add parameters for aclocal
+AC_SUBST(ACLOCAL_AMFLAGS, "-I M4")
+
AC_LANG([C])
#------------------------------------------------------------------------------------
@@ -33,7 +40,7 @@ SHARED_VERSION_INFO="1:18:0"
AC_PROG_CC
AM_PROG_LIBTOOL
-AC_CHECK_PROG(autogen, autogen, yes, no)
+AC_CHECK_PROG(HAVE_AUTOGEN, autogen, yes, no)
AC_PROG_INSTALL
AC_PROG_LN_S
@@ -43,7 +50,6 @@ AC_HEADER_STDC
AC_CHECK_HEADERS(endian.h)
AC_CHECK_HEADERS(byteswap.h)
AC_CHECK_HEADERS(locale.h)
-AC_CHECK_HEADERS(inttypes.h)
AC_HEADER_SYS_WAIT
@@ -259,6 +265,13 @@ case "$host_os" in
;;
esac
+#====================================================================================
+# Check for requirements for building plugins for other languages/enviroments.
+
+dnl Octave maths environment http://www.octave.org/
+AC_OCTAVE_BUILD
+
+
#====================================================================================
# Check for libsqlite3 (only used in regtest).
@@ -466,7 +479,7 @@ if test $ac_cv_sizeof_double != 8 ; then
AC_MSG_WARN([[******************************************************************]])
fi
-if test x"$ac_cv_prog_autogen" = "xno" ; then
+if test x"$ac_cv_prog_HAVE_AUTOGEN" = "xno" ; then
AC_MSG_WARN([[Touching files in directory tests/.]])
touch tests/*.c tests/*.h
fi
@@ -611,16 +624,13 @@ AC_CONFIG_FILES([ \
src/FLAC/src/share/utf8/Makefile src/FLAC/src/test_libFLAC/Makefile \
src/FLAC/src/test_libs_common/Makefile src/FLAC/src/test_seeking/Makefile \
src/FLAC/src/test_streams/Makefile src/FLAC/test/Makefile \
- src/FLAC/src/monkeys_audio_utilities/Makefile \
- src/FLAC/src/monkeys_audio_utilities/flac_mac/Makefile \
- src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile \
src/FLAC/src/test_grabbag/Makefile src/FLAC/src/test_grabbag/cuesheet/Makefile \
src/FLAC/src/test_grabbag/picture/Makefile \
\
src/OGG/include/ogg/Makefile src/OGG/include/Makefile src/OGG/Makefile \
man/Makefile examples/Makefile tests/Makefile regtest/Makefile \
- doc/Makefile doc/libsndfile.css \
- Win32/Makefile Octave/Makefile \
+ M4/Makefile doc/Makefile Win32/Makefile Octave/Makefile \
+ doc/libsndfile.css \
Makefile libsndfile.spec sndfile.pc \
])
AC_OUTPUT
diff --git a/doc/development.html b/doc/development.html
index 61fbda42..ee0d2218 100644
--- a/doc/development.html
+++ b/doc/development.html
@@ -33,7 +33,8 @@ it on windows.
-The main archive archive can be found at:
+The main archive archive can be found at (yes, the directory looks empty,
+but it isn't):
http://www.mega-nerd.com/Bzr/libsndfile-pub/
diff --git a/doc/index.html b/doc/index.html
index fce8c4fb..f2bcd0ad 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -282,8 +282,12 @@
FLAC.
- I have decided that I will not be adding support for MPEG Layer 3 due to the
- patent issues surrounding this file format.
+ I have decided that I will not be adding support for MPEG Layer 3 (commonly
+ known as MP3) due to the patent issues surrounding this file format.
+ See
+
+ the FAQ
+ for more.
Other file formats may also be added on request.
diff --git a/examples/generate.c b/examples/generate.c
index 1b0eec79..d0433130 100644
--- a/examples/generate.c
+++ b/examples/generate.c
@@ -1,19 +1,33 @@
/*
-** Copyright (C) 2002-2005 Erik de Castro Lopo
+** Copyright (C) 2002-2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sfconfig.h"
diff --git a/examples/list_formats.c b/examples/list_formats.c
index 0b6db499..24b6b7c8 100644
--- a/examples/list_formats.c
+++ b/examples/list_formats.c
@@ -1,19 +1,33 @@
/*
-** Copyright (C) 2001-2005 Erik de Castro Lopo
+** Copyright (C) 2001-2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
diff --git a/examples/make_sine.c b/examples/make_sine.c
index 3a50c26f..e7b9e0f4 100644
--- a/examples/make_sine.c
+++ b/examples/make_sine.c
@@ -1,19 +1,33 @@
/*
-** Copyright (C) 1999-2005 Erik de Castro Lopo
+** Copyright (C) 1999-2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
diff --git a/examples/paf_write.c b/examples/paf_write.c
deleted file mode 100644
index 394b2a35..00000000
--- a/examples/paf_write.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-** Copyright (C) 1999-2005 Erik de Castro Lopo
-**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-
-#include
-#include
-#include
-
-#include
-
-#define SAMPLE_RATE 8000
-#define SAMPLE_COUNT 100
-
-int
-main (void)
-{ SNDFILE *file ;
- SF_INFO sfinfo ;
- char *filename ;
- int k, buffer [SAMPLE_COUNT] ;
-
- for (k = 0 ; k < SAMPLE_COUNT ; k++)
- buffer [k] = ((3 * k + 2) << 24) + ((3 * k + 1) << 16) + ((3 * k) << 8) ;
-
- /* Big endian first. */
- sfinfo.samplerate = SAMPLE_RATE ;
- sfinfo.frames = SAMPLE_COUNT ;
- sfinfo.channels = 1 ;
- sfinfo.format = (SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_24) ;
-
- filename = "be-pcm24.paf" ;
-
- if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
- { printf ("Error : Not able to open output file.\n") ;
- return 1 ;
- } ;
-
- printf ("Writing data to '%s'\n", filename) ;
-
- if (sf_write_int (file, buffer, SAMPLE_COUNT) != SAMPLE_COUNT)
- puts (sf_strerror (file)) ;
-
- sf_close (file) ;
-
- /* Little endian first. */
- sfinfo.samplerate = SAMPLE_RATE ;
- sfinfo.frames = SAMPLE_COUNT ;
- sfinfo.channels = 1 ;
- sfinfo.format = (SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_24) ;
-
- filename = "le-pcm24.paf" ;
-
- if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
- { printf ("Error : Not able to open output file.\n") ;
- return 1 ;
- } ;
-
- printf ("Writing data to '%s'\n", filename) ;
-
- if (sf_write_int (file, buffer, SAMPLE_COUNT) != SAMPLE_COUNT)
- puts (sf_strerror (file)) ;
-
- sf_close (file) ;
-
- return 0 ;
-} /* main */
-
-/*
-** Do not edit or modify anything in this comment block.
-** The arch-tag line is a file identity tag for the GNU Arch
-** revision control system.
-**
-** arch-tag: 62025b88-1f3f-46fb-994a-8220bf915772
-*/
diff --git a/examples/sfprocess.c b/examples/sfprocess.c
index e48fcfb6..43144750 100644
--- a/examples/sfprocess.c
+++ b/examples/sfprocess.c
@@ -1,19 +1,33 @@
/*
** Copyright (C) 2001-2005 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
diff --git a/examples/sndfile-convert.c b/examples/sndfile-convert.c
index 7072382e..a9d0751a 100644
--- a/examples/sndfile-convert.c
+++ b/examples/sndfile-convert.c
@@ -1,22 +1,35 @@
/*
-** Copyright (C) 1999-2005 Erik de Castro Lopo
+** Copyright (C) 1999-2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include
#include
#include
diff --git a/examples/sndfile-data-trim.c b/examples/sndfile-data-trim.c
index 25b8f921..e2cd4f80 100644
--- a/examples/sndfile-data-trim.c
+++ b/examples/sndfile-data-trim.c
@@ -1,19 +1,33 @@
/*
** Copyright (C) 2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*/
diff --git a/examples/sndfile-info.c b/examples/sndfile-info.c
index 44e2ec17..d6f3945a 100644
--- a/examples/sndfile-info.c
+++ b/examples/sndfile-info.c
@@ -1,19 +1,33 @@
/*
-** Copyright (C) 1999-2006 Erik de Castro Lopo
+** Copyright (C) 1999-2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
diff --git a/examples/sndfile-play.c b/examples/sndfile-play.c
index 60ebf93a..abcd1da2 100644
--- a/examples/sndfile-play.c
+++ b/examples/sndfile-play.c
@@ -1,19 +1,33 @@
/*
-** Copyright (C) 1999-2005 Erik de Castro Lopo
+** Copyright (C) 1999-2007 Erik de Castro Lopo
**
-** 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.
+** All rights reserved.
**
-** 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.
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
**
-** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** * 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 author nor the names of any contributors may be used
+** to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sfconfig.h"
diff --git a/reconfigure.mk b/reconfigure.mk
deleted file mode 100755
index bd65bc82..00000000
--- a/reconfigure.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/make -f
-
-# The auto tools MUST be run in the following order:
-#
-# 1. aclocal
-# 2. libtoolize (if you use libtool)
-# 3. autoconf
-# 4. autoheader (if you use autoheader)
-# 5. automake (if you use automake)
-#
-# The following makefile runs these in the correct order according to their
-# dependancies. It also makes up for Mac OSX's fucked-upped-ness.
-
-ACLOCAL = aclocal
-
-ifneq ($(shell uname -s), Darwin)
- LIBTOOLIZE = libtoolize
-else
- # Fuck Apple! Why the hell did they rename libtoolize????
- LIBTOOLIZE = glibtoolize
- # Fink (and DarwinPorts/MacPorts) sucks as well, but this seems necessary.
- ACLOCAL_INC = -I /opt/local/share/aclocal
-endif
-
-genfiles : config.status
- (cd src && make genfiles)
- (cd tests && make genfiles)
-
-config.status: configure src/config.h.in Makefile.in src/Makefile.in tests/Makefile.in
- ./configure --enable-gcc-werror
-
-configure: ltmain.sh
- autoconf
-
-Makefile.in: Makefile.am
- automake --copy --add-missing
-
-src/Makefile.in: src/Makefile.am
- automake --copy --add-missing
-
-tests/Makefile.in: tests/Makefile.am
- automake --copy --add-missing
-
-src/config.h.in: configure
- autoheader
-
-libtool ltmain.sh: aclocal.m4
- $(LIBTOOLIZE) --copy --force
-
-# Need to re-run aclocal whenever acinclude.m4 is modified.
-aclocal.m4: acinclude.m4
- $(ACLOCAL) $(ACLOCAL_INC)
-
-clean:
- rm -f libtool ltmain.sh aclocal.m4 src/config.h.in config.cache config.status
- rm -rf autom4te.cache
- find . -name Makefile.in -exec rm -f {} \;
- find . -name .deps -type d -exec rm -rf {} \;
-
diff --git a/src/FLAC/include/FLAC/Makefile.am b/src/FLAC/include/FLAC/Makefile.am
index 19f49b1f..7a80fe60 100644
--- a/src/FLAC/include/FLAC/Makefile.am
+++ b/src/FLAC/include/FLAC/Makefile.am
@@ -28,9 +28,7 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-flaccincludedir = $(includedir)/FLAC
-
-flaccinclude_HEADERS = \
+noinst_HEADERS = \
all.h \
assert.h \
callback.h \
diff --git a/src/FLAC/include/FLAC/all.h b/src/FLAC/include/FLAC/all.h
index 1611a261..66ccdd2a 100644
--- a/src/FLAC/include/FLAC/all.h
+++ b/src/FLAC/include/FLAC/all.h
@@ -141,6 +141,11 @@
* encoder, and no metadata interface, you can remove the stream encoder
* and the metadata interface, which will greatly reduce the size of the
* library.
+ *
+ * Also, there are several places in the libFLAC code with comments marked
+ * with "OPT:" where a #define can be changed to enable code that might be
+ * faster on a specific platform. Experimenting with these can yield faster
+ * binaries.
*/
/** \defgroup porting Porting Guide for New Versions
diff --git a/src/FLAC/include/FLAC/metadata.h b/src/FLAC/include/FLAC/metadata.h
index f9796aea..c679e79f 100644
--- a/src/FLAC/include/FLAC/metadata.h
+++ b/src/FLAC/include/FLAC/metadata.h
@@ -32,6 +32,7 @@
#ifndef FLAC__METADATA_H
#define FLAC__METADATA_H
+#include /* for off_t */
#include "export.h"
#include "callback.h"
#include "format.h"
@@ -443,6 +444,37 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIte
*/
FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator);
+/*@@@@add to tests*/
+/** Returns a flag telling if the current metadata block is the last.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c true if the current metadata block is the last in the file,
+ * else \c false.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator);
+
+/*@@@@add to tests*/
+/** Get the offset of the metadata block at the current position. This
+ * avoids reading the actual block data which can save time for large
+ * blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval off_t
+ * The offset of the metadata block at the current iterator position.
+ * This is the byte offset relative to the beginning of the file of
+ * the current metadata block's header.
+ */
+FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator);
+
/** Get the type of the metadata block at the current position. This
* avoids reading the actual block data which can save time for large
* blocks.
@@ -455,9 +487,52 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte
* \retval FLAC__MetadataType
* The type of the metadata block at the current iterator position.
*/
-
FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator);
+/*@@@@add to tests*/
+/** Get the length of the metadata block at the current position. This
+ * avoids reading the actual block data which can save time for large
+ * blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval unsigned
+ * The length of the metadata block at the current iterator position.
+ * The is same length as that in the
+ * metadata block header,
+ * i.e. the length of the metadata body that follows the header.
+ */
+FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator);
+
+/*@@@@add to tests*/
+/** Get the application ID of the \c APPLICATION block at the current
+ * position. This avoids reading the actual block data which can save
+ * time for large blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param id A pointer to a buffer of at least \c 4 bytes where
+ * the ID will be stored.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \code id != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c true if the ID was successfully read, else \c false, in which
+ * case you should check FLAC__metadata_simple_iterator_status() to
+ * find out why. If the status is
+ * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the
+ * current metadata block is not an \c APPLICATION block. Otherwise
+ * if the status is
+ * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or
+ * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error
+ * occurred and the iterator can no longer be used.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id);
+
/** Get the metadata block at the current position. You can modify the
* block but must use FLAC__metadata_simple_iterator_set_block() to
* write it back to the FLAC file.
@@ -471,7 +546,8 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const
* \a iterator has been successfully initialized with
* FLAC__metadata_simple_iterator_init()
* \retval FLAC__StreamMetadata*
- * The current metadata block.
+ * The current metadata block, or \c NULL if there was a memory
+ * allocation error.
*/
FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator);
diff --git a/src/FLAC/include/share/Makefile.am b/src/FLAC/include/share/Makefile.am
index b50d883d..513828b8 100644
--- a/src/FLAC/include/share/Makefile.am
+++ b/src/FLAC/include/share/Makefile.am
@@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = grabbag
EXTRA_DIST = \
+ alloc.h \
getopt.h \
grabbag.h \
replaygain_analysis.h \
diff --git a/src/FLAC/include/share/alloc.h b/src/FLAC/include/share/alloc.h
new file mode 100644
index 00000000..63b12f3b
--- /dev/null
+++ b/src/FLAC/include/share/alloc.h
@@ -0,0 +1,210 @@
+/* alloc - Convenience routines for safely allocating memory
+ * Copyright (C) 2007 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FLAC__SHARE__ALLOC_H
+#define FLAC__SHARE__ALLOC_H
+
+#if HAVE_CONFIG_H
+# include
+#endif
+
+/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
+ * before #including this file, otherwise SIZE_MAX might not be defined
+ */
+
+#include /* for SIZE_MAX */
+#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
+#include /* for SIZE_MAX in case limits.h didn't get it */
+#endif
+#include /* for size_t, malloc(), etc */
+
+#ifndef SIZE_MAX
+# ifndef SIZE_T_MAX
+# ifdef _MSC_VER
+# define SIZE_T_MAX UINT_MAX
+# else
+# error
+# endif
+# endif
+# define SIZE_MAX SIZE_T_MAX
+#endif
+
+#define FLaC__INLINE inline
+
+/* avoid malloc()ing 0 bytes, see:
+ * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
+*/
+static FLaC__INLINE void *safe_malloc_(size_t size)
+{
+ /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ if(!size)
+ size++;
+ return malloc(size);
+}
+
+static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size)
+{
+ if(!nmemb || !size)
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ return calloc(nmemb, size);
+}
+
+/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
+
+static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ return safe_malloc_(size2);
+}
+
+static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ return safe_malloc_(size3);
+}
+
+static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ size4 += size3;
+ if(size4 < size3)
+ return 0;
+ return safe_malloc_(size4);
+}
+
+static FLaC__INLINE void *safe_malloc_mul_2op_(size_t size1, size_t size2)
+#if 0
+needs support for cases where sizeof(size_t) != 4
+{
+ /* could be faster #ifdef'ing off SIZEOF_SIZE_T */
+ if(sizeof(size_t) == 4) {
+ if ((double)size1 * (double)size2 < 4294967296.0)
+ return malloc(size1*size2);
+ }
+ return 0;
+}
+#else
+/* better? */
+{
+ 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);
+}
+#endif
+
+static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || !size2 || !size3)
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ if(size1 > SIZE_MAX / size2)
+ return 0;
+ size1 *= size2;
+ if(size1 > SIZE_MAX / size3)
+ return 0;
+ return malloc(size1*size3);
+}
+
+/* size1*size2 + size3 */
+static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || !size2)
+ return safe_malloc_(size3);
+ if(size1 > SIZE_MAX / size2)
+ return 0;
+ return safe_malloc_add_2op_(size1*size2, size3);
+}
+
+/* size1 * (size2 + size3) */
+static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || (!size2 && !size3))
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ size2 += size3;
+ if(size2 < size3)
+ return 0;
+ return safe_malloc_mul_2op_(size1, size2);
+}
+
+static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ return realloc(ptr, size2);
+}
+
+static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ return realloc(ptr, size3);
+}
+
+static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ size4 += size3;
+ if(size4 < size3)
+ return 0;
+ return realloc(ptr, size4);
+}
+
+static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
+{
+ if(!size1 || !size2)
+ return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
+ if(size1 > SIZE_MAX / size2)
+ return 0;
+ return realloc(ptr, size1*size2);
+}
+
+/* size1 * (size2 + size3) */
+static FLaC__INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || (!size2 && !size3))
+ return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
+ size2 += size3;
+ if(size2 < size3)
+ return 0;
+ return safe_realloc_mul_2op_(ptr, size1, size2);
+}
+
+#endif
diff --git a/src/FLAC/include/test_libs_common/metadata_utils.h b/src/FLAC/include/test_libs_common/metadata_utils.h
index e1e87b30..2f0f3eef 100644
--- a/src/FLAC/include/test_libs_common/metadata_utils.h
+++ b/src/FLAC/include/test_libs_common/metadata_utils.h
@@ -24,9 +24,6 @@
*/
#include "FLAC/format.h"
-#include
-#include /* for malloc() */
-#include /* for memcmp() */
FLAC__bool mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo *block, const FLAC__StreamMetadata_StreamInfo *blockcopy);
diff --git a/src/FLAC/src/Makefile.am b/src/FLAC/src/Makefile.am
index ec715bb3..1c292c5c 100644
--- a/src/FLAC/src/Makefile.am
+++ b/src/FLAC/src/Makefile.am
@@ -18,7 +18,6 @@
SUBDIRS = \
libFLAC \
share \
- monkeys_audio_utilities \
test_grabbag \
test_libs_common \
test_libFLAC \
diff --git a/src/FLAC/src/libFLAC/bitwriter.c b/src/FLAC/src/libFLAC/bitwriter.c
index 848ed4d6..683daac1 100644
--- a/src/FLAC/src/libFLAC/bitwriter.c
+++ b/src/FLAC/src/libFLAC/bitwriter.c
@@ -44,6 +44,7 @@
#include "private/bitwriter.h"
#include "private/crc.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
/* Things should be fastest when this matches the machine word size */
/* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */
@@ -127,7 +128,7 @@ static FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add)
FLAC__ASSERT(new_capacity > bw->capacity);
FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD));
- new_buffer = (bwword*)realloc(bw->buffer, sizeof(bwword)*new_capacity);
+ new_buffer = (bwword*)safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
if(new_buffer == 0)
return false;
bw->buffer = new_buffer;
diff --git a/src/FLAC/src/libFLAC/format.c b/src/FLAC/src/libFLAC/format.c
index 25d69372..68580948 100644
--- a/src/FLAC/src/libFLAC/format.c
+++ b/src/FLAC/src/libFLAC/format.c
@@ -61,9 +61,9 @@ FLAC_API const char *FLAC__VERSION_STRING = "1.2.0";
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__
/* yet one more hack because of MSVC6: */
-FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 20070715";
+FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 CVS-20070820";
#else
-FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC CVS 1.2.0 20070715";
+FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 CVS-20070820";
#endif
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
diff --git a/src/FLAC/src/libFLAC/include/private/md5.h b/src/FLAC/src/libFLAC/include/private/md5.h
index 659912c5..e5f675a8 100644
--- a/src/FLAC/src/libFLAC/include/private/md5.h
+++ b/src/FLAC/src/libFLAC/include/private/md5.h
@@ -33,7 +33,7 @@ typedef struct {
FLAC__uint32 buf[4];
FLAC__uint32 bytes[2];
FLAC__byte *internal_buf;
- unsigned capacity;
+ size_t capacity;
} FLAC__MD5Context;
void FLAC__MD5Init(FLAC__MD5Context *context);
diff --git a/src/FLAC/src/libFLAC/lpc.c b/src/FLAC/src/libFLAC/lpc.c
index 26d1382e..7806348f 100644
--- a/src/FLAC/src/libFLAC/lpc.c
+++ b/src/FLAC/src/libFLAC/lpc.c
@@ -569,7 +569,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
#else /* fully unrolled version for normal use */
{
- unsigned i;
+ int i;
FLAC__int64 sum;
FLAC__ASSERT(order > 0);
@@ -584,7 +584,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
if(order > 8) {
if(order > 10) {
if(order == 12) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
@@ -602,7 +602,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
}
else { /* order == 11 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
@@ -621,7 +621,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
else {
if(order == 10) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
@@ -637,7 +637,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
}
else { /* order == 9 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
@@ -656,7 +656,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
else if(order > 4) {
if(order > 6) {
if(order == 8) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
@@ -670,7 +670,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
}
else { /* order == 7 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
@@ -685,7 +685,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
else {
if(order == 6) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
@@ -697,7 +697,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
}
else { /* order == 5 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
@@ -712,7 +712,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
else {
if(order > 2) {
if(order == 4) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
@@ -722,7 +722,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
}
else { /* order == 3 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
@@ -733,7 +733,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
else {
if(order == 2) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
@@ -741,14 +741,14 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
}
}
else { /* order == 1 */
- for(i = 0; i < data_len; i++)
+ for(i = 0; i < (int)data_len; i++)
residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
}
}
}
}
else { /* order > 12 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
switch(order) {
case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32];
@@ -1099,7 +1099,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
#else /* fully unrolled version for normal use */
{
- unsigned i;
+ int i;
FLAC__int64 sum;
FLAC__ASSERT(order > 0);
@@ -1114,7 +1114,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
if(order > 8) {
if(order > 10) {
if(order == 12) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
@@ -1132,7 +1132,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
}
else { /* order == 11 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
@@ -1151,7 +1151,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
else {
if(order == 10) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
@@ -1167,7 +1167,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
}
else { /* order == 9 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
@@ -1186,7 +1186,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
else if(order > 4) {
if(order > 6) {
if(order == 8) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
@@ -1200,7 +1200,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
}
else { /* order == 7 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
@@ -1215,7 +1215,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
else {
if(order == 6) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
@@ -1227,7 +1227,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
}
else { /* order == 5 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
@@ -1242,7 +1242,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
else {
if(order > 2) {
if(order == 4) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
@@ -1252,7 +1252,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
}
else { /* order == 3 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
@@ -1263,7 +1263,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
else {
if(order == 2) {
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
@@ -1271,14 +1271,14 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
}
else { /* order == 1 */
- for(i = 0; i < data_len; i++)
+ for(i = 0; i < (int)data_len; i++)
data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
}
}
}
}
else { /* order > 12 */
- for(i = 0; i < data_len; i++) {
+ for(i = 0; i < (int)data_len; i++) {
sum = 0;
switch(order) {
case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32];
diff --git a/src/FLAC/src/libFLAC/md5.c b/src/FLAC/src/libFLAC/md5.c
index 47e163f9..37cef67b 100644
--- a/src/FLAC/src/libFLAC/md5.c
+++ b/src/FLAC/src/libFLAC/md5.c
@@ -6,6 +6,7 @@
#include /* for memcpy() */
#include "private/md5.h"
+#include "share/alloc.h"
#ifndef FLaC__INLINE
#define FLaC__INLINE
@@ -396,13 +397,19 @@ static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], u
*/
FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
{
- const unsigned bytes_needed = channels * samples * bytes_per_sample;
+ const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
+
+ /* overflow check */
+ if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
+ return false;
+ if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
+ return false;
if(ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed);
if(0 == tmp) {
free(ctx->internal_buf);
- if(0 == (ctx->internal_buf = (FLAC__byte*)malloc(bytes_needed)))
+ if(0 == (ctx->internal_buf = (FLAC__byte*)safe_malloc_(bytes_needed)))
return false;
}
ctx->internal_buf = tmp;
diff --git a/src/FLAC/src/libFLAC/memory.c b/src/FLAC/src/libFLAC/memory.c
index 7c7aee94..4d100975 100644
--- a/src/FLAC/src/libFLAC/memory.c
+++ b/src/FLAC/src/libFLAC/memory.c
@@ -35,6 +35,7 @@
#include "private/memory.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
{
@@ -44,7 +45,7 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
#ifdef FLAC__ALIGN_MALLOC_DATA
/* align on 32-byte (256-bit) boundary */
- x = malloc(bytes+31);
+ x = safe_malloc_add_2op_(bytes, /*+*/31);
#ifdef SIZEOF_VOIDP
#if SIZEOF_VOIDP == 4
/* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */
@@ -64,7 +65,7 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
return 0;
#endif
#else
- x = malloc(bytes);
+ x = safe_malloc_(bytes);
*aligned_address = x;
#endif
return x;
@@ -83,7 +84,10 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(FLAC__int32) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -109,7 +113,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint32) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -135,7 +142,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint64) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -161,7 +171,10 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -189,7 +202,10 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real *
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(FLAC__real) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
diff --git a/src/FLAC/src/libFLAC/metadata_iterators.c b/src/FLAC/src/libFLAC/metadata_iterators.c
index a36540ff..b99cb5f3 100644
--- a/src/FLAC/src/libFLAC/metadata_iterators.c
+++ b/src/FLAC/src/libFLAC/metadata_iterators.c
@@ -61,6 +61,7 @@
#include "FLAC/assert.h"
#include "FLAC/stream_decoder.h"
+#include "share/alloc.h"
#ifdef max
#undef max
@@ -577,6 +578,22 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte
return true;
}
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator)
+{
+ FLAC__ASSERT(0 != iterator);
+ FLAC__ASSERT(0 != iterator->file);
+
+ return iterator->is_last;
+}
+
+FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator)
+{
+ FLAC__ASSERT(0 != iterator);
+ FLAC__ASSERT(0 != iterator->file);
+
+ return iterator->offset[iterator->depth];
+}
+
FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator)
{
FLAC__ASSERT(0 != iterator);
@@ -585,6 +602,41 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const
return iterator->type;
}
+FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator)
+{
+ FLAC__ASSERT(0 != iterator);
+ FLAC__ASSERT(0 != iterator->file);
+
+ return iterator->length;
+}
+
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id)
+{
+ const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
+
+ FLAC__ASSERT(0 != iterator);
+ FLAC__ASSERT(0 != iterator->file);
+ FLAC__ASSERT(0 != id);
+
+ if(iterator->type != FLAC__METADATA_TYPE_APPLICATION) {
+ iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT;
+ return false;
+ }
+
+ if(fread(id, 1, id_bytes, iterator->file) != id_bytes) {
+ iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+ return false;
+ }
+
+ /* back up */
+ if(0 != fseeko(iterator->file, -((int)id_bytes), SEEK_CUR)) {
+ iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
+ return false;
+ }
+
+ return true;
+}
+
FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator)
{
FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type);
@@ -2101,6 +2153,9 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLA
if(read_cb(block->id, 1, id_bytes, handle) != id_bytes)
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+ if(block_length < id_bytes)
+ return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+
block_length -= id_bytes;
if(block_length == 0) {
@@ -2128,7 +2183,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC_
if(block->num_points == 0)
block->points = 0;
- else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint))))
+ else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(block->num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint))))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
for(i = 0; i < block->num_points; i++) {
@@ -2161,7 +2216,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entr
entry->entry = 0;
}
else {
- if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
+ if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_2op_(entry->length, /*+*/1)))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
@@ -2336,7 +2391,7 @@ static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstr
if(0 != *data)
free(*data);
- if(0 == (*data = (FLAC__byte*)malloc(*length+1)))
+ if(0 == (*data = (FLAC__byte*)safe_malloc_add_2op_(*length, /*+*/1)))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
if(*length > 0) {
@@ -2365,7 +2420,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cb_(FLAC__I
len = FLAC__STREAM_METADATA_PICTURE_TYPE_LEN / 8;
if(read_cb(buffer, 1, len, handle) != len)
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
- block->type = unpack_uint32_(buffer, len);
+ block->type = (FLAC__StreamMetadata_Picture_Type)unpack_uint32_(buffer, len);
if((status = read_metadata_block_data_picture_cstring_cb_(handle, read_cb, (FLAC__byte**)(&(block->mime_type)), &len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK)
return status;
@@ -3155,7 +3210,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix
{
static const char *tempfile_suffix = ".metadata_edit";
if(0 == tempfile_path_prefix) {
- if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) {
+ if(0 == (*tempfilename = (char*)safe_malloc_add_3op_(strlen(filename), /*+*/strlen(tempfile_suffix), /*+*/1))) {
*status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -3169,7 +3224,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix
else
p++;
- if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) {
+ if(0 == (*tempfilename = (char*)safe_malloc_add_4op_(strlen(tempfile_path_prefix), /*+*/strlen(p), /*+*/strlen(tempfile_suffix), /*+*/2))) {
*status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
return false;
}
diff --git a/src/FLAC/src/libFLAC/metadata_object.c b/src/FLAC/src/libFLAC/metadata_object.c
index 75117670..c7f16db1 100644
--- a/src/FLAC/src/libFLAC/metadata_object.c
+++ b/src/FLAC/src/libFLAC/metadata_object.c
@@ -39,6 +39,7 @@
#include "private/metadata.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
/****************************************************************************
@@ -53,14 +54,14 @@
* from != NULL && bytes > 0
* to <- copy of from
* else ASSERT
- * malloc error leaved 'to' unchanged
+ * malloc error leaves 'to' unchanged
*/
static FLAC__bool copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes)
{
FLAC__ASSERT(0 != to);
if(bytes > 0 && 0 != from) {
FLAC__byte *x;
- if(0 == (x = (FLAC__byte*)malloc(bytes)))
+ if(0 == (x = (FLAC__byte*)safe_malloc_(bytes)))
return false;
memcpy(x, from, bytes);
*to = x;
@@ -94,7 +95,7 @@ static FLAC__bool free_copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsi
/* realloc() failure leaves entry unchanged */
static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length)
{
- FLAC__byte *x = (FLAC__byte*)realloc(*entry, length+1);
+ FLAC__byte *x = (FLAC__byte*)safe_realloc_add_2op_(*entry, length, /*+*/1);
if(0 != x) {
x[length] = '\0';
*entry = x;
@@ -132,7 +133,7 @@ static FLAC__bool copy_vcentry_(FLAC__StreamMetadata_VorbisComment_Entry *to, co
else {
FLAC__byte *x;
FLAC__ASSERT(from->length > 0);
- if(0 == (x = (FLAC__byte*)malloc(from->length+1)))
+ if(0 == (x = (FLAC__byte*)safe_malloc_add_2op_(from->length, /*+*/1)))
return false;
memcpy(x, from->entry, from->length);
x[from->length] = '\0';
@@ -150,7 +151,7 @@ static FLAC__bool copy_track_(FLAC__StreamMetadata_CueSheet_Track *to, const FLA
else {
FLAC__StreamMetadata_CueSheet_Index *x;
FLAC__ASSERT(from->num_indices > 0);
- if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)malloc(from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index))))
+ if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)safe_malloc_mul_2op_(from->num_indices, /*times*/sizeof(FLAC__StreamMetadata_CueSheet_Index))))
return false;
memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
to->indices = x;
@@ -172,7 +173,7 @@ static FLAC__StreamMetadata_SeekPoint *seekpoint_array_new_(unsigned num_points)
FLAC__ASSERT(num_points > 0);
- object_array = (FLAC__StreamMetadata_SeekPoint*)malloc(num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
+ object_array = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint));
if(0 != object_array) {
unsigned i;
@@ -205,7 +206,7 @@ static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_new_(
{
FLAC__ASSERT(num_comments > 0);
- return (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
+ return (FLAC__StreamMetadata_VorbisComment_Entry*)safe_calloc_(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
}
static void vorbiscomment_entry_array_delete_(FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments)
@@ -344,14 +345,14 @@ static FLAC__StreamMetadata_CueSheet_Index *cuesheet_track_index_array_new_(unsi
{
FLAC__ASSERT(num_indices > 0);
- return (FLAC__StreamMetadata_CueSheet_Index*)calloc(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index));
+ return (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index));
}
static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks)
{
FLAC__ASSERT(num_tracks > 0);
- return (FLAC__StreamMetadata_CueSheet_Track*)calloc(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
+ return (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
}
static void cuesheet_track_array_delete_(FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks)
@@ -537,6 +538,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet
case FLAC__METADATA_TYPE_PADDING:
break;
case FLAC__METADATA_TYPE_APPLICATION:
+ if(to->length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) { /* underflow check */
+ FLAC__metadata_object_delete(to);
+ return 0;
+ }
memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8);
if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) {
FLAC__metadata_object_delete(to);
@@ -545,6 +550,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet
break;
case FLAC__METADATA_TYPE_SEEKTABLE:
to->data.seek_table.num_points = object->data.seek_table.num_points;
+ if(to->data.seek_table.num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) { /* overflow check */
+ FLAC__metadata_object_delete(to);
+ return 0;
+ }
if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) {
FLAC__metadata_object_delete(to);
return 0;
@@ -930,8 +939,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMe
return false;
}
else {
- const unsigned old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
- const unsigned new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+ const size_t old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+ const size_t new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+
+ /* overflow check */
+ if((size_t)new_num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint))
+ return false;
FLAC__ASSERT(object->data.seek_table.num_points > 0);
@@ -1157,8 +1170,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__St
return false;
}
else {
- const unsigned old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
- const unsigned new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+ const size_t old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+ const size_t new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+
+ /* overflow check */
+ if((size_t)new_num_comments > SIZE_MAX / sizeof(FLAC__StreamMetadata_VorbisComment_Entry))
+ return false;
FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0);
@@ -1306,7 +1323,7 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pa
const size_t nn = strlen(field_name);
const size_t nv = strlen(field_value);
entry->length = nn + 1 /*=*/ + nv;
- if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
+ if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_4op_(nn, /*+*/1, /*+*/nv, /*+*/1)))
return false;
memcpy(entry->entry, field_name, nn);
entry->entry[nn] = '=';
@@ -1333,9 +1350,9 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair
FLAC__ASSERT(0 != eq);
if(0 == eq)
return false; /* double protection */
- if(0 == (*field_name = (char*)malloc(nn+1)))
+ if(0 == (*field_name = (char*)safe_malloc_add_2op_(nn, /*+*/1)))
return false;
- if(0 == (*field_value = (char*)malloc(nv+1))) {
+ if(0 == (*field_value = (char*)safe_malloc_add_2op_(nv, /*+*/1))) {
free(*field_name);
return false;
}
@@ -1465,8 +1482,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__St
return false;
}
else {
- const unsigned old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
- const unsigned new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+ const size_t old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+ const size_t new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+
+ /* overflow check */
+ if((size_t)new_num_indices > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Index))
+ return false;
FLAC__ASSERT(track->num_indices > 0);
@@ -1549,8 +1570,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMet
return false;
}
else {
- const unsigned old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
- const unsigned new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+ const size_t old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+ const size_t new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+
+ /* overflow check */
+ if((size_t)new_num_tracks > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Track))
+ return false;
FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0);
@@ -1707,6 +1732,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMeta
/* do the copy first so that if we fail we leave the object untouched */
if(copy) {
+ if(new_length >= SIZE_MAX) /* overflow check */
+ return false;
if(!copy_bytes_((FLAC__byte**)(&object->data.picture.mime_type), (FLAC__byte*)mime_type, new_length+1))
return false;
}
@@ -1737,6 +1764,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMe
/* do the copy first so that if we fail we leave the object untouched */
if(copy) {
+ if(new_length >= SIZE_MAX) /* overflow check */
+ return false;
if(!copy_bytes_(&object->data.picture.description, description, new_length+1))
return false;
}
diff --git a/src/FLAC/src/libFLAC/ogg_helper.c b/src/FLAC/src/libFLAC/ogg_helper.c
index aeaf99f4..73f9f0be 100644
--- a/src/FLAC/src/libFLAC/ogg_helper.c
+++ b/src/FLAC/src/libFLAC/ogg_helper.c
@@ -36,6 +36,7 @@
#include /* for malloc() */
#include /* for memcmp(), memcpy() */
#include "FLAC/assert.h"
+#include "share/alloc.h"
#include "private/ogg_helper.h"
#include "protected/stream_encoder.h"
@@ -112,7 +113,7 @@ FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 po
}
/* allocate space for the page header */
- if(0 == (page->header = (unsigned char *)malloc(OGG_MAX_HEADER_LEN))) {
+ if(0 == (page->header = (unsigned char *)safe_malloc_(OGG_MAX_HEADER_LEN))) {
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -154,7 +155,7 @@ FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 po
}
/* allocate space for the page body */
- if(0 == (page->body = (unsigned char *)malloc(page->body_len))) {
+ if(0 == (page->body = (unsigned char *)safe_malloc_(page->body_len))) {
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false;
}
diff --git a/src/FLAC/src/libFLAC/stream_decoder.c b/src/FLAC/src/libFLAC/stream_decoder.c
index 864f6800..6240dfb2 100644
--- a/src/FLAC/src/libFLAC/stream_decoder.c
+++ b/src/FLAC/src/libFLAC/stream_decoder.c
@@ -53,6 +53,7 @@
#endif
#endif
#include "FLAC/assert.h"
+#include "share/alloc.h"
#include "protected/stream_decoder.h"
#include "private/bitreader.h"
#include "private/bitmath.h"
@@ -181,7 +182,7 @@ typedef struct FLAC__StreamDecoderPrivate {
FLAC__StreamMetadata seek_table;
FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
FLAC__byte *metadata_filter_ids;
- unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
+ size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
FLAC__Frame frame;
FLAC__bool cached; /* true if there is a byte in lookahead */
FLAC__CPUInfo cpuinfo;
@@ -784,7 +785,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) {
+ if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -843,7 +844,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__S
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) {
+ if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1287,9 +1288,11 @@ FILE *get_binary_stdin_(void)
*/
#if defined _MSC_VER || defined __MINGW32__
_setmode(_fileno(stdin), _O_BINARY);
-#elif defined __CYGWIN__ || defined __EMX__
+#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;
@@ -1323,7 +1326,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne
* (at negative indices) for alignment purposes; we use 4
* to keep the data well-aligned.
*/
- tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4));
+ tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/);
if(tmp == 0) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
@@ -1348,7 +1351,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne
FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
{
- unsigned i;
+ size_t i;
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
@@ -1469,6 +1472,11 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))
return false; /* read_callback_ sets the state for us */
+ if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */
+ decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/
+ return false;
+ }
+
real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
@@ -1531,7 +1539,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
if(!decoder->private_->is_seeking && decoder->private_->metadata_callback)
decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
- /* now we have to free any malloc'ed data in the block */
+ /* now we have to free any malloc()ed data in the block */
switch(type) {
case FLAC__METADATA_TYPE_PADDING:
break;
@@ -1671,7 +1679,7 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_
decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
/* use realloc since we may pass through here several times (e.g. after seeking) */
- if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) {
+ if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1710,7 +1718,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */
if(obj->vendor_string.length > 0) {
- if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) {
+ if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1728,7 +1736,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
/* read comments */
if(obj->num_comments > 0) {
- if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
+ if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1737,7 +1745,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
return false; /* read_callback_ sets the state for us */
if(obj->comments[i].length > 0) {
- if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) {
+ if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1783,7 +1791,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
obj->num_tracks = x;
if(obj->num_tracks > 0) {
- if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
+ if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1816,7 +1824,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
track->num_indices = (FLAC__byte)x;
if(track->num_indices > 0) {
- if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
+ if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1853,7 +1861,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
/* read MIME type */
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
return false; /* read_callback_ sets the state for us */
- if(0 == (obj->mime_type = (char*)malloc(x+1))) {
+ if(0 == (obj->mime_type = (char*)safe_malloc_add_2op_(x, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1866,7 +1874,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
/* read description */
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
return false; /* read_callback_ sets the state for us */
- if(0 == (obj->description = (FLAC__byte*)malloc(x+1))) {
+ if(0 == (obj->description = (FLAC__byte*)safe_malloc_add_2op_(x, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1895,7 +1903,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
/* read data */
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
return false; /* read_callback_ sets the state for us */
- if(0 == (obj->data = (FLAC__byte*)malloc(obj->data_length))) {
+ if(0 == (obj->data = (FLAC__byte*)safe_malloc_(obj->data_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -2043,6 +2051,8 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL
}
if(!read_zero_padding_(decoder))
return false;
+ if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */
+ return true;
/*
* Read the frame CRC-16 from the footer and check
@@ -2078,7 +2088,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL
decoder->private_->output[0][i] = (mid + side) >> 1;
decoder->private_->output[1][i] = (mid - side) >> 1;
#else
- //@@@@@@ OPT: try without 'side' temp variable
+ /* OPT: without 'side' temp variable */
mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */
decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1;
decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1;
@@ -3178,7 +3188,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint
{
FLAC__uint64 left_pos = 0, right_pos = stream_length;
FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder);
- FLAC__uint64 this_frame_sample = 0; /* only initialized to avoid compiler warning */
+ FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1;
FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */
FLAC__bool did_a_seek;
unsigned iteration = 0;
diff --git a/src/FLAC/src/libFLAC/stream_encoder.c b/src/FLAC/src/libFLAC/stream_encoder.c
index 41531ac6..bb4f5f4b 100644
--- a/src/FLAC/src/libFLAC/stream_encoder.c
+++ b/src/FLAC/src/libFLAC/stream_encoder.c
@@ -54,6 +54,7 @@
#endif
#include "FLAC/assert.h"
#include "FLAC/stream_decoder.h"
+#include "share/alloc.h"
#include "protected/stream_encoder.h"
#include "private/bitwriter.h"
#include "private/bitmath.h"
@@ -198,6 +199,7 @@ static unsigned evaluate_fixed_subframe_(
unsigned subframe_bps,
unsigned order,
unsigned rice_parameter,
+ unsigned rice_parameter_limit,
unsigned min_partition_order,
unsigned max_partition_order,
FLAC__bool do_escape_coding,
@@ -219,6 +221,7 @@ static unsigned evaluate_lpc_subframe_(
unsigned order,
unsigned qlp_coeff_precision,
unsigned rice_parameter,
+ unsigned rice_parameter_limit,
unsigned min_partition_order,
unsigned max_partition_order,
FLAC__bool do_escape_coding,
@@ -244,12 +247,13 @@ static unsigned find_best_partition_order_(
unsigned residual_samples,
unsigned predictor_order,
unsigned rice_parameter,
+ unsigned rice_parameter_limit,
unsigned min_partition_order,
unsigned max_partition_order,
unsigned bps,
FLAC__bool do_escape_coding,
unsigned rice_parameter_search_dist,
- FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice
+ FLAC__EntropyCodingMethod *best_ecm
);
static void precompute_partition_info_sums_(
@@ -280,6 +284,7 @@ static FLAC__bool set_partitioned_rice_(
const unsigned residual_samples,
const unsigned predictor_order,
const unsigned suggested_rice_parameter,
+ const unsigned rice_parameter_limit,
const unsigned rice_parameter_search_dist,
const unsigned partition_order,
const FLAC__bool search_for_escapes,
@@ -987,7 +992,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
*/
encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_;
for(i = 0; i < encoder->protected_->channels; i++) {
- if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder->private_->verify.input_fifo.size))) {
+ if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)safe_malloc_mul_2op_(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) {
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
}
@@ -1726,7 +1731,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encod
}
if(num_blocks) {
FLAC__StreamMetadata **m;
- if(0 == (m = (FLAC__StreamMetadata**)malloc(sizeof(m[0]) * num_blocks)))
+ if(0 == (m = (FLAC__StreamMetadata**)safe_malloc_mul_2op_(sizeof(m[0]), /*times*/num_blocks)))
return false;
memcpy(m, metadata, sizeof(m[0]) * num_blocks);
encoder->protected_->metadata = m;
@@ -3197,6 +3202,8 @@ FLAC__bool process_subframe_(
unsigned rice_parameter;
unsigned _candidate_bits, _best_bits;
unsigned _best_subframe;
+ /* only use RICE2 partitions if stream bps > 16 */
+ const unsigned rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
FLAC__ASSERT(frame_header->blocksize > 0);
@@ -3259,11 +3266,11 @@ FLAC__bool process_subframe_(
rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */
#endif
rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
- if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ if(rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
+ fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1);
#endif
- rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+ rice_parameter = rice_parameter_limit - 1;
}
_candidate_bits =
evaluate_fixed_subframe_(
@@ -3276,6 +3283,7 @@ FLAC__bool process_subframe_(
subframe_bps,
fixed_order,
rice_parameter,
+ rice_parameter_limit,
min_partition_order,
max_partition_order,
encoder->protected_->do_escape_coding,
@@ -3330,11 +3338,11 @@ FLAC__bool process_subframe_(
continue; /* don't even try */
rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */
rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
- if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ if(rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
+ fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1);
#endif
- rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+ rice_parameter = rice_parameter_limit - 1;
}
if(encoder->protected_->do_qlp_coeff_prec_search) {
min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
@@ -3363,6 +3371,7 @@ FLAC__bool process_subframe_(
lpc_order,
qlp_coeff_precision,
rice_parameter,
+ rice_parameter_limit,
min_partition_order,
max_partition_order,
encoder->protected_->do_escape_coding,
@@ -3502,6 +3511,7 @@ unsigned evaluate_fixed_subframe_(
unsigned subframe_bps,
unsigned order,
unsigned rice_parameter,
+ unsigned rice_parameter_limit,
unsigned min_partition_order,
unsigned max_partition_order,
FLAC__bool do_escape_coding,
@@ -3530,12 +3540,13 @@ unsigned evaluate_fixed_subframe_(
residual_samples,
order,
rice_parameter,
+ rice_parameter_limit,
min_partition_order,
max_partition_order,
subframe_bps,
do_escape_coding,
rice_parameter_search_dist,
- &subframe->data.fixed.entropy_coding_method.data.partitioned_rice
+ &subframe->data.fixed.entropy_coding_method
);
subframe->data.fixed.order = order;
@@ -3564,6 +3575,7 @@ unsigned evaluate_lpc_subframe_(
unsigned order,
unsigned qlp_coeff_precision,
unsigned rice_parameter,
+ unsigned rice_parameter_limit,
unsigned min_partition_order,
unsigned max_partition_order,
FLAC__bool do_escape_coding,
@@ -3611,12 +3623,13 @@ unsigned evaluate_lpc_subframe_(
residual_samples,
order,
rice_parameter,
+ rice_parameter_limit,
min_partition_order,
max_partition_order,
subframe_bps,
do_escape_coding,
rice_parameter_search_dist,
- &subframe->data.lpc.entropy_coding_method.data.partitioned_rice
+ &subframe->data.lpc.entropy_coding_method
);
subframe->data.lpc.order = order;
@@ -3669,16 +3682,18 @@ unsigned find_best_partition_order_(
unsigned residual_samples,
unsigned predictor_order,
unsigned rice_parameter,
+ unsigned rice_parameter_limit,
unsigned min_partition_order,
unsigned max_partition_order,
unsigned bps,
FLAC__bool do_escape_coding,
unsigned rice_parameter_search_dist,
- FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice
+ FLAC__EntropyCodingMethod *best_ecm
)
{
unsigned residual_bits, best_residual_bits = 0;
unsigned best_parameters_index = 0;
+ unsigned best_partition_order = 0;
const unsigned blocksize = residual_samples + predictor_order;
max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order);
@@ -3704,6 +3719,7 @@ unsigned find_best_partition_order_(
residual_samples,
predictor_order,
rice_parameter,
+ rice_parameter_limit,
rice_parameter_search_dist,
(unsigned)partition_order,
do_escape_coding,
@@ -3719,20 +3735,37 @@ unsigned find_best_partition_order_(
if(best_residual_bits == 0 || residual_bits < best_residual_bits) {
best_residual_bits = residual_bits;
best_parameters_index = !best_parameters_index;
- best_partitioned_rice->order = partition_order;
+ best_partition_order = partition_order;
}
}
}
- /*
- * We are allowed to de-const the pointer based on our special knowledge;
- * it is const to the outside world.
- */
+ best_ecm->data.partitioned_rice.order = best_partition_order;
+
{
- FLAC__EntropyCodingMethod_PartitionedRiceContents* best_partitioned_rice_contents = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_partitioned_rice->contents;
- FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(best_partitioned_rice_contents, max(6, best_partitioned_rice->order));
- memcpy(best_partitioned_rice_contents->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partitioned_rice->order)));
- memcpy(best_partitioned_rice_contents->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partitioned_rice->order)));
+ /*
+ * We are allowed to de-const the pointer based on our special
+ * knowledge; it is const to the outside world.
+ */
+ FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents;
+ unsigned partition;
+
+ /* save best parameters and raw_bits */
+ FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, max(6, best_partition_order));
+ memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partition_order)));
+ if(do_escape_coding)
+ memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order)));
+ /*
+ * Now need to check if the type should be changed to
+ * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the
+ * size of the rice parameters.
+ */
+ for(partition = 0; partition < (1u<parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2;
+ break;
+ }
+ }
}
return best_residual_bits;
@@ -3885,7 +3918,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_(
)
{
unsigned i, partition_bits =
- FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN +
+ FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */
(1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */
;
for(i = 0; i < partition_samples; i++)
@@ -3900,7 +3933,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_(
)
{
return
- FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN +
+ FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */
(1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */
(
rice_parameter?
@@ -3927,6 +3960,7 @@ FLAC__bool set_partitioned_rice_(
const unsigned residual_samples,
const unsigned predictor_order,
const unsigned suggested_rice_parameter,
+ const unsigned rice_parameter_limit,
const unsigned rice_parameter_search_dist,
const unsigned partition_order,
const FLAC__bool search_for_escapes,
@@ -3944,7 +3978,8 @@ FLAC__bool set_partitioned_rice_(
(void)rice_parameter_search_dist;
#endif
- FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER);
+ FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
+ FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order));
parameters = partitioned_rice_contents->parameters;
@@ -3959,11 +3994,11 @@ FLAC__bool set_partitioned_rice_(
else
min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist;
max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist;
- if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ if(max_rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
+ fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1);
#endif
- max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+ max_rice_parameter = rice_parameter_limit - 1;
}
}
else
@@ -3986,12 +4021,14 @@ FLAC__bool set_partitioned_rice_(
}
#endif
if(search_for_escapes) {
- partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples;
+ partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples;
if(partition_bits <= best_partition_bits) {
raw_bits[0] = raw_bits_per_partition[0];
- best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
+ best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
best_partition_bits = partition_bits;
}
+ else
+ raw_bits[0] = 0;
}
parameters[0] = best_rice_parameter;
bits_ += best_partition_bits;
@@ -4020,11 +4057,11 @@ FLAC__bool set_partitioned_rice_(
*/
for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1)
;
- if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ if(rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
+ fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);
#endif
- rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+ rice_parameter = rice_parameter_limit - 1;
}
best_partition_bits = (unsigned)(-1);
@@ -4035,11 +4072,11 @@ FLAC__bool set_partitioned_rice_(
else
min_rice_parameter = rice_parameter - rice_parameter_search_dist;
max_rice_parameter = rice_parameter + rice_parameter_search_dist;
- if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ if(max_rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
+ fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1);
#endif
- max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+ max_rice_parameter = rice_parameter_limit - 1;
}
}
else
@@ -4060,12 +4097,14 @@ FLAC__bool set_partitioned_rice_(
}
#endif
if(search_for_escapes) {
- partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
+ partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
if(partition_bits <= best_partition_bits) {
raw_bits[partition] = raw_bits_per_partition[partition];
- best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
+ best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
best_partition_bits = partition_bits;
}
+ else
+ raw_bits[partition] = 0;
}
parameters[partition] = best_rice_parameter;
bits_ += best_partition_bits;
diff --git a/src/FLAC/src/libFLAC/stream_encoder_framing.c b/src/FLAC/src/libFLAC/stream_encoder_framing.c
index 07e40f9c..1cb9cf60 100644
--- a/src/FLAC/src/libFLAC/stream_encoder_framing.c
+++ b/src/FLAC/src/libFLAC/stream_encoder_framing.c
@@ -45,7 +45,7 @@
#define max(x,y) ((x)>(y)?(x):(y))
static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method);
-static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order);
+static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended);
FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw)
{
@@ -229,7 +229,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit
if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN))
+ if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN))
return false;
FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
@@ -253,10 +253,8 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit
default:
if(header->blocksize <= 0x100)
blocksize_hint = u = 6;
- else if(header->blocksize <= 0x10000)
- blocksize_hint = u = 7;
else
- u = 0;
+ blocksize_hint = u = 7;
break;
}
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN))
@@ -265,14 +263,17 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit
FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate));
sample_rate_hint = 0;
switch(header->sample_rate) {
- case 8000: u = 4; break;
- case 16000: u = 5; break;
- case 22050: u = 6; break;
- case 24000: u = 7; break;
- case 32000: u = 8; break;
- case 44100: u = 9; break;
- case 48000: u = 10; break;
- case 96000: u = 11; break;
+ case 88200: u = 1; break;
+ case 176400: u = 2; break;
+ case 192000: u = 3; break;
+ case 8000: u = 4; break;
+ case 16000: u = 5; break;
+ case 22050: u = 6; break;
+ case 24000: u = 7; break;
+ case 32000: u = 8; break;
+ case 44100: u = 9; break;
+ case 48000: u = 10; break;
+ case 96000: u = 11; break;
default:
if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0)
sample_rate_hint = u = 12;
@@ -325,9 +326,14 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit
if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN))
return false;
- FLAC__ASSERT(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER);
- if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number))
- return false;
+ if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
+ if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number))
+ return false;
+ }
+ else {
+ if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number))
+ return false;
+ }
if(blocksize_hint)
if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16))
@@ -388,7 +394,17 @@ FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsign
return false;
switch(subframe->entropy_coding_method.type) {
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- if(!add_residual_partitioned_rice_(bw, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order))
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
+ if(!add_residual_partitioned_rice_(
+ bw,
+ subframe->residual,
+ residual_samples,
+ subframe->order,
+ subframe->entropy_coding_method.data.partitioned_rice.contents->parameters,
+ subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits,
+ subframe->entropy_coding_method.data.partitioned_rice.order,
+ /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2
+ ))
return false;
break;
default:
@@ -424,7 +440,17 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned r
return false;
switch(subframe->entropy_coding_method.type) {
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- if(!add_residual_partitioned_rice_(bw, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order))
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
+ if(!add_residual_partitioned_rice_(
+ bw,
+ subframe->residual,
+ residual_samples,
+ subframe->order,
+ subframe->entropy_coding_method.data.partitioned_rice.contents->parameters,
+ subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits,
+ subframe->entropy_coding_method.data.partitioned_rice.order,
+ /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2
+ ))
return false;
break;
default:
@@ -458,6 +484,7 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo
return false;
switch(method->type) {
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
return false;
break;
@@ -467,18 +494,24 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo
return true;
}
-FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order)
+FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended)
{
+ const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
+ const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
+
if(partition_order == 0) {
unsigned i;
- if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
- return false;
- if(rice_parameters[0] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+ if(raw_bits[0] == 0) {
+ if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen))
+ return false;
if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0]))
return false;
}
else {
+ FLAC__ASSERT(rice_parameters[0] == 0);
+ if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen))
+ return false;
if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
return false;
for(i = 0; i < residual_samples; i++) {
@@ -493,17 +526,19 @@ FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32
unsigned partition_samples;
const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order;
for(i = 0; i < (1u<
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-static int execit(char *prog, char *args);
-static int forkit(char *prog, char *args);
-
-int main(int argc, char *argv[])
-{
- int flac_return_val = 0, opt_arg = 1, from_arg = -1, to_arg = -1, flac_level = 5, i;
- char prog[MAX_PATH], cmdline[MAX_PATH*2], from[MAX_PATH], to[MAX_PATH], macdir[MAX_PATH], options[256], *p;
- enum { WAVPACK, RKAU, SHORTEN } codec;
-
- /* get the directory where MAC external codecs reside */
- if(0 != (p = strrchr(argv[0],'\\'))) {
- strcpy(macdir, argv[0]);
- *(strrchr(macdir,'\\')+1) = '\0';
- }
- else {
- strcpy(macdir, "");
- }
-
- /* determine which codec we were called as and parse the options */
- if(p == 0)
- p = argv[0];
- else
- p++;
- if(0 == strnicmp(p, "short", 5)) {
- codec = SHORTEN;
- }
- else if(0 == strnicmp(p, "rkau", 4)) {
- codec = RKAU;
- if(argv[1][0] == '-' && argv[1][1] == 'l') {
- opt_arg = 2;
- switch(argv[1][2]) {
- case '1': flac_level = 1; break;
- case '2': flac_level = 5; break;
- case '3': flac_level = 8; break;
- }
- }
- }
- else if(0 == strnicmp(p, "wavpack", 7)) {
- codec = WAVPACK;
- if(argv[1][0] == '-') {
- opt_arg = 2;
- switch(argv[1][1]) {
- case 'f': flac_level = 1; break;
- case 'h': flac_level = 8; break;
- default: opt_arg = 1;
- }
- }
- }
- else {
- return -5;
- }
-
- /* figure out which arguments are the source and destination files */
- for(i = 1; i < argc; i++)
- if(argv[i][0] != '-') {
- from_arg = i++;
- break;
- }
- for( ; i < argc; i++)
- if(argv[i][0] != '-') {
- to_arg = i++;
- break;
- }
- if(to_arg < 0)
- return -4;
-
- /* build the command to call flac with */
- sprintf(prog, "%sflac.exe", macdir);
- sprintf(options, "-%d", flac_level);
- for(i = opt_arg; i < argc; i++)
- if(argv[i][0] == '-') {
- strcat(options, " ");
- strcat(options, argv[i]);
- }
- sprintf(cmdline, "\"%s\" %s -o \"%s\" \"%s\"", prog, options, argv[to_arg], argv[from_arg]);
-
- flac_return_val = execit(prog, cmdline);
-
- /*
- * Now that flac has finished, we need to fork a process that will rename
- * the resulting file with the correct extension once MAC has moved it to
- * it's final resting place.
- */
- if(0 == flac_return_val) {
- /* get the destination directory, if any */
- if(0 != (p = strchr(argv[to_arg],'\\'))) {
- strcpy(from, argv[to_arg]);
- *(strrchr(from,'\\')+1) = '\0';
- }
- else {
- strcpy(from, "");
- }
-
- /* for the full 'from' and 'to' paths for the renamer process */
- p = strrchr(argv[from_arg],'\\');
- strcat(from, p? p+1 : argv[from_arg]);
- strcpy(to, from);
- if(0 == strchr(from,'.'))
- return -3;
- switch(codec) {
- case SHORTEN: strcpy(strrchr(from,'.'), ".shn"); break;
- case WAVPACK: strcpy(strrchr(from,'.'), ".wv"); break;
- case RKAU: strcpy(strrchr(from,'.'), ".rka"); break;
- }
- strcpy(strrchr(to,'.'), ".flac");
-
- sprintf(prog, "%sflac_ren.exe", macdir);
- sprintf(cmdline, "\"%s\" \"%s\" \"%s\"", prog, from, to);
-
- flac_return_val = forkit(prog, cmdline);
- }
-
- return flac_return_val;
-}
-
-int execit(char *prog, char *args)
-{
- BOOL ok;
- STARTUPINFO startup_info;
- PROCESS_INFORMATION proc_info;
-
- GetStartupInfo(&startup_info);
-
- ok = CreateProcess(
- prog,
- args,
- 0, /*process security attributes*/
- 0, /*thread security attributes*/
- FALSE,
- 0, /*dwCreationFlags*/
- 0, /*environment*/
- 0, /*lpCurrentDirectory*/
- &startup_info,
- &proc_info
- );
- if(ok) {
- DWORD dw;
- dw = WaitForSingleObject(proc_info.hProcess, INFINITE);
- ok = (dw != 0xFFFFFFFF);
- CloseHandle(proc_info.hThread);
- CloseHandle(proc_info.hProcess);
- }
-
- return ok? 0 : -1;
-}
-
-int forkit(char *prog, char *args)
-{
- BOOL ok;
- STARTUPINFO startup_info;
- PROCESS_INFORMATION proc_info;
-
- GetStartupInfo(&startup_info);
-
- ok = CreateProcess(
- prog,
- args,
- 0, /*process security attributes*/
- 0, /*thread security attributes*/
- FALSE,
- DETACHED_PROCESS, /*dwCreationFlags*/
- 0, /*environment*/
- 0, /*lpCurrentDirectory*/
- &startup_info,
- &proc_info
- );
- if(ok) {
- CloseHandle(proc_info.hThread);
- CloseHandle(proc_info.hProcess);
- }
-
- return ok? 0 : -2;
-}
diff --git a/src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile.am b/src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile.am
deleted file mode 100644
index 57c6a7c5..00000000
--- a/src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile.am
+++ /dev/null
@@ -1,19 +0,0 @@
-# flac_ren - renamer part of utility to add FLAC support to Monkey's Audio
-# Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-EXTRA_DIST = \
- main.c
diff --git a/src/FLAC/src/monkeys_audio_utilities/flac_ren/main.c b/src/FLAC/src/monkeys_audio_utilities/flac_ren/main.c
deleted file mode 100644
index fa849836..00000000
--- a/src/FLAC/src/monkeys_audio_utilities/flac_ren/main.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* flac_ren - renamer part of utility to add FLAC support to Monkey's Audio
- * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#if HAVE_CONFIG_H
-# include
-#endif
-
-#include
-#include
-#include
-#include
-
-int main(int argc, char *argv[])
-{
- struct stat s;
-
- /* wait till the 'from' file has reached its final destination */
- do {
- Sleep(2000);
- } while(stat(argv[1], &s) < 0);
-
- /* now rename it */
- return rename(argv[1], argv[2]);
-}
diff --git a/src/FLAC/src/share/grabbag/cuesheet.c b/src/FLAC/src/share/grabbag/cuesheet.c
index a30fa033..1220b74b 100644
--- a/src/FLAC/src/share/grabbag/cuesheet.c
+++ b/src/FLAC/src/share/grabbag/cuesheet.c
@@ -398,9 +398,21 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message,
*error_message = "TRACK number must be greater than 0";
return false;
}
- if(is_cdda && in_track_num > 99) {
- *error_message = "CD-DA TRACK number must be between 1 and 99, inclusive";
- 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";
@@ -503,7 +515,7 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message,
}
if(!has_forced_leadout) {
- forced_leadout_track_num = is_cdda? 170 : cs->num_tracks;
+ 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)) {
diff --git a/src/FLAC/src/share/grabbag/file.c b/src/FLAC/src/share/grabbag/file.c
index a481f743..d073c4bf 100644
--- a/src/FLAC/src/share/grabbag/file.c
+++ b/src/FLAC/src/share/grabbag/file.c
@@ -42,8 +42,8 @@
#include /* for strrchr() */
#if defined _WIN32 && !defined __CYGWIN__
// for GetFileInformationByHandle() etc
-#include
-#include
+#include
+#include
#endif
#include "share/grabbag.h"
diff --git a/src/FLAC/src/share/grabbag/picture.c b/src/FLAC/src/share/grabbag/picture.c
index 68e1f51d..d3e0e180 100644
--- a/src/FLAC/src/share/grabbag/picture.c
+++ b/src/FLAC/src/share/grabbag/picture.c
@@ -20,6 +20,7 @@
# include
#endif
+#include "share/alloc.h"
#include "share/grabbag.h"
#include "FLAC/assert.h"
#include
@@ -29,7 +30,7 @@
/* 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 = (char*)malloc(size+1);
+ char *x = (char*)safe_malloc_add_2op_(size, /*+*/1);
if(x) {
memcpy(x, s, size);
x[size] = '\0';
@@ -357,7 +358,7 @@ FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, con
if(size < 0)
*error_message = error_messages[5];
else {
- FLAC__byte *buffer = (FLAC__byte*)malloc(size);
+ FLAC__byte *buffer = (FLAC__byte*)safe_malloc_(size);
if(0 == buffer)
*error_message = error_messages[0];
else {
diff --git a/src/FLAC/src/share/utf8/charset.c b/src/FLAC/src/share/utf8/charset.c
index 1610ad22..5bff506c 100644
--- a/src/FLAC/src/share/utf8/charset.c
+++ b/src/FLAC/src/share/utf8/charset.c
@@ -35,6 +35,7 @@
#include
+#include "alloc.h"
#include "charset.h"
#include "charmaps.h"
@@ -493,7 +494,7 @@ int charset_convert(const char *fromcode, const char *tocode,
if (!charset1 || !charset2 )
return -1;
- tobuf = (char *)malloc(fromlen * charset2->max + 1);
+ tobuf = (char *)safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1);
if (!tobuf)
return -2;
diff --git a/src/FLAC/src/share/utf8/iconvert.c b/src/FLAC/src/share/utf8/iconvert.c
index 37f16a89..f0311ee0 100644
--- a/src/FLAC/src/share/utf8/iconvert.c
+++ b/src/FLAC/src/share/utf8/iconvert.c
@@ -29,6 +29,7 @@
#include
#include "iconvert.h"
+#include "share/alloc.h"
/*
* Convert data from one encoding to another. Return:
@@ -81,7 +82,7 @@ int iconvert(const char *fromcode, const char *tocode,
* This is deliberately not a config option as people often
* change their iconv library without rebuilding applications.
*/
- tocode1 = (char *)malloc(strlen(tocode) + 11);
+ tocode1 = (char *)safe_malloc_add_2op_(strlen(tocode), /*+*/11);
if (!tocode1)
goto fail;
@@ -119,6 +120,8 @@ int iconvert(const char *fromcode, const char *tocode,
break;
if (obl < 6) {
/* Enlarge the buffer */
+ if(utflen*2 < utflen) /* overflow check */
+ goto fail;
utflen *= 2;
newbuf = (char *)realloc(utfbuf, utflen);
if (!newbuf)
@@ -145,7 +148,7 @@ int iconvert(const char *fromcode, const char *tocode,
iconv_close(cd1);
return ret;
}
- newbuf = (char *)realloc(utfbuf, (ob - utfbuf) + 1);
+ newbuf = (char *)safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
if (!newbuf)
goto fail;
ob = (ob - utfbuf) + newbuf;
@@ -196,7 +199,7 @@ int iconvert(const char *fromcode, const char *tocode,
outlen += ob - tbuf;
/* Convert from UTF-8 for real */
- outbuf = (char *)malloc(outlen + 1);
+ outbuf = (char *)safe_malloc_add_2op_(outlen, /*+*/1);
if (!outbuf)
goto fail;
ib = utfbuf;
diff --git a/src/FLAC/src/share/utf8/utf8.c b/src/FLAC/src/share/utf8/utf8.c
index f2bf5704..867511da 100644
--- a/src/FLAC/src/share/utf8/utf8.c
+++ b/src/FLAC/src/share/utf8/utf8.c
@@ -2,6 +2,8 @@
* Copyright (C) 2001 Peter Harris
* Copyright (C) 2001 Edmund Grimley Evans
*
+ * Buffer overflow checking added: Josh Coalson, 9/9/2007
+ *
* 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
@@ -28,6 +30,7 @@
#include
#include
+#include "alloc.h"
#include "utf8.h"
#include "charset.h"
@@ -43,7 +46,8 @@
static unsigned char *make_utf8_string(const wchar_t *unicode)
{
- int size = 0, index = 0, out_index = 0;
+ size_t size = 0, n;
+ int index = 0, out_index = 0;
unsigned char *out;
unsigned short c;
@@ -51,16 +55,19 @@ static unsigned char *make_utf8_string(const wchar_t *unicode)
c = unicode[index++];
while(c) {
if(c < 0x0080) {
- size += 1;
+ n = 1;
} else if(c < 0x0800) {
- size += 2;
+ n = 2;
} else {
- size += 3;
+ n = 3;
}
+ if(size+n < size) /* overflow check */
+ return NULL;
+ size += n;
c = unicode[index++];
- }
+ }
- out = malloc(size + 1);
+ out = safe_malloc_add_2op_(size, /*+*/1);
if (out == NULL)
return NULL;
index = 0;
@@ -87,7 +94,8 @@ static unsigned char *make_utf8_string(const wchar_t *unicode)
static wchar_t *make_unicode_string(const unsigned char *utf8)
{
- int size = 0, index = 0, out_index = 0;
+ size_t size = 0;
+ int index = 0, out_index = 0;
wchar_t *out;
unsigned char c;
@@ -101,11 +109,15 @@ static wchar_t *make_unicode_string(const unsigned char *utf8)
} else {
index += 1;
}
- size += 1;
+ if(size + 1 == 0) /* overflow check */
+ return NULL;
+ size++;
c = utf8[index++];
- }
+ }
- out = malloc((size + 1) * sizeof(wchar_t));
+ if(size + 1 == 0) /* overflow check */
+ return NULL;
+ out = safe_malloc_mul_2op_(size+1, /*times*/sizeof(wchar_t));
if (out == NULL)
return NULL;
index = 0;
@@ -147,7 +159,10 @@ int utf8_encode(const char *from, char **to)
return -1;
}
- unicode = calloc(wchars + 1, sizeof(unsigned short));
+ if(wchars < 0) /* underflow check */
+ return -1;
+
+ unicode = safe_calloc_((size_t)wchars + 1, sizeof(unsigned short));
if(unicode == NULL)
{
fprintf(stderr, "Out of memory processing string to UTF8\n");
@@ -190,6 +205,9 @@ int utf8_decode(const char *from, char **to)
chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode,
-1, NULL, 0, NULL, NULL);
+ if(chars < 0) /* underflow check */
+ return -1;
+
if(chars == 0)
{
fprintf(stderr, "Unicode translation error %d\n", GetLastError());
@@ -197,7 +215,7 @@ int utf8_decode(const char *from, char **to)
return -1;
}
- *to = calloc(chars + 1, sizeof(unsigned char));
+ *to = safe_calloc_((size_t)chars + 1, sizeof(unsigned char));
if(*to == NULL)
{
fprintf(stderr, "Out of memory processing string to local charset\n");
@@ -277,7 +295,7 @@ static int convert_string(const char *fromcode, const char *tocode,
if (ret != -1)
return ret;
- s = malloc(fromlen + 1);
+ s = safe_malloc_add_2op_(fromlen, /*+*/1);
if (!s)
return -1;
strcpy(s, from);
diff --git a/src/FLAC/src/test_libFLAC/decoders.c b/src/FLAC/src/test_libFLAC/decoders.c
index 9e77caca..1d731cd4 100644
--- a/src/FLAC/src/test_libFLAC/decoders.c
+++ b/src/FLAC/src/test_libFLAC/decoders.c
@@ -66,7 +66,7 @@ static off_t flacfilesize_;
static const char *flacfilename(FLAC__bool is_ogg)
{
- return is_ogg? "metadata.ogg" : "metadata.flac";
+ return is_ogg? "metadata.oga" : "metadata.flac";
}
static FLAC__bool die_(const char *msg)
diff --git a/src/FLAC/src/test_libFLAC/encoders.c b/src/FLAC/src/test_libFLAC/encoders.c
index c1de7ba3..5927cb83 100644
--- a/src/FLAC/src/test_libFLAC/encoders.c
+++ b/src/FLAC/src/test_libFLAC/encoders.c
@@ -51,7 +51,7 @@ static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metada
static const char *flacfilename(FLAC__bool is_ogg)
{
- return is_ogg? "metadata.ogg" : "metadata.flac";
+ return is_ogg? "metadata.oga" : "metadata.flac";
}
static FLAC__bool die_(const char *msg)
diff --git a/src/FLAC/src/test_libFLAC/metadata_manip.c b/src/FLAC/src/test_libFLAC/metadata_manip.c
index 5f00b8cc..b3875318 100644
--- a/src/FLAC/src/test_libFLAC/metadata_manip.c
+++ b/src/FLAC/src/test_libFLAC/metadata_manip.c
@@ -73,7 +73,7 @@ static unsigned mc_our_block_number_ = 0;
static const char *flacfilename(FLAC__bool is_ogg)
{
- return is_ogg? "metadata.ogg" : "metadata.flac";
+ return is_ogg? "metadata.oga" : "metadata.flac";
}
static FLAC__bool die_(const char *msg)
@@ -315,7 +315,7 @@ static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_paddi
if(FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
struct stat stats;
- FILE *file, *tempfile;
+ FILE *file, *tempfile = 0;
char *tempfilename;
if(preserve_file_stats) {
if(!get_file_stats_(filename, &stats))
diff --git a/src/FLAC/src/test_seeking/main.c b/src/FLAC/src/test_seeking/main.c
index 6bcd58db..2559b89a 100644
--- a/src/FLAC/src/test_seeking/main.c
+++ b/src/FLAC/src/test_seeking/main.c
@@ -75,6 +75,21 @@ static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
return false;
}
+static unsigned local_rand_(void)
+{
+#if !defined _MSC_VER && !defined __MINGW32__
+#define RNDFUNC random
+#else
+#define RNDFUNC rand
+#endif
+ /* every RAND_MAX I've ever seen is 2^15-1 or 2^31-1, so a little hackery here: */
+ if (RAND_MAX > 32767)
+ return RNDFUNC();
+ else /* usually MSVC, some solaris */
+ return (RNDFUNC()<<15) | RNDFUNC();
+#undef RNDFUNC
+}
+
static off_t get_filesize_(const char *srcpath)
{
struct stat srcstat;
@@ -88,7 +103,7 @@ static off_t get_filesize_(const char *srcpath)
static FLAC__bool read_pcm_(FLAC__int32 *pcm[], const char *rawfilename, const char *flacfilename)
{
FILE *f;
- unsigned channels, bps = 0, samples, i, j;
+ unsigned channels = 0, bps = 0, samples, i, j;
off_t rawfilesize = get_filesize_(rawfilename);
if (rawfilesize < 0) {
@@ -298,12 +313,6 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi
printf("file's total_samples is %I64u\n", decoder_client_data.total_samples);
#else
printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples);
-#endif
-#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
- if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) {
- printf("ERROR: must be total_samples < %u\n", (unsigned)RAND_MAX);
- return false;
- }
#endif
n = (long int)decoder_client_data.total_samples;
@@ -315,10 +324,6 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi
if(n == 0) {
/* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */
n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample);
-#if !defined _MSC_VER && !defined __MINGW32__
- if(n > RAND_MAX)
- n = RAND_MAX;
-#endif
}
printf("Begin seek barrage, count=%u\n", count);
@@ -339,12 +344,7 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi
pos = n + (i-20);
}
else {
-#if !defined _MSC_VER && !defined __MINGW32__
- pos = (FLAC__uint64)(random() % n);
-#else
- /* RAND_MAX is only 32767 in my MSVC */
- pos = (FLAC__uint64)((rand()<<15|rand()) % n);
-#endif
+ pos = (FLAC__uint64)(local_rand_() % n);
}
#ifdef _MSC_VER
@@ -386,6 +386,7 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi
printf("OK\n");
fflush(stdout);
}
+ stop_signal_ = false;
if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
if(!FLAC__stream_decoder_finish(decoder))
@@ -480,7 +481,7 @@ int main(int argc, char *argv[])
/* no need to do "decode all" read_mode if PCM checking is available */
if (rawfilename && read_mode > 1)
continue;
- if (strlen(flacfilename) > 4 && 0 == strcmp(flacfilename+strlen(flacfilename)-4, ".ogg")) {
+ if (strlen(flacfilename) > 4 && (0 == strcmp(flacfilename+strlen(flacfilename)-4, ".oga") || 0 == strcmp(flacfilename+strlen(flacfilename)-4, ".ogg"))) {
#if FLAC__HAS_OGG
ok = seek_barrage(/*is_ogg=*/true, flacfilename, flacfilesize, count, samples, read_mode, rawfilename? pcm : 0);
#else
diff --git a/src/FLAC/src/test_streams/main.c b/src/FLAC/src/test_streams/main.c
index f3f14ecf..c335776d 100644
--- a/src/FLAC/src/test_streams/main.c
+++ b/src/FLAC/src/test_streams/main.c
@@ -36,12 +36,6 @@
#define M_PI 3.14159265358979323846
#endif
-#if defined _WIN32 || defined __EMX__
- static const char *mode = "wb";
-#else
- static const char *mode = "w";
-#endif
-
#if !defined _MSC_VER && !defined __MINGW32__
#define GET_RANDOM_BYTE (((unsigned)random()) & 0xff)
#else
@@ -211,7 +205,7 @@ static FLAC__bool generate_01(void)
FILE *f;
FLAC__int16 x = -32768;
- if(0 == (f = fopen("test01.raw", mode)))
+ if(0 == (f = fopen("test01.raw", "wb")))
return false;
if(!write_little_endian_int16(f, x))
@@ -230,7 +224,7 @@ static FLAC__bool generate_02(void)
FILE *f;
FLAC__int16 xl = -32768, xr = 32767;
- if(0 == (f = fopen("test02.raw", mode)))
+ if(0 == (f = fopen("test02.raw", "wb")))
return false;
if(!write_little_endian_int16(f, xl))
@@ -252,7 +246,7 @@ static FLAC__bool generate_03(void)
FLAC__int16 x[] = { -25, 0, 25, 50, 100 };
unsigned i;
- if(0 == (f = fopen("test03.raw", mode)))
+ if(0 == (f = fopen("test03.raw", "wb")))
return false;
for(i = 0; i < 5; i++)
@@ -273,7 +267,7 @@ static FLAC__bool generate_04(void)
FLAC__int16 x[] = { -25, 500, 0, 400, 25, 300, 50, 200, 100, 100 };
unsigned i;
- if(0 == (f = fopen("test04.raw", mode)))
+ if(0 == (f = fopen("test04.raw", "wb")))
return false;
for(i = 0; i < 10; i++)
@@ -295,7 +289,7 @@ static FLAC__bool generate_fsd8(const char *fn, const int pattern[], unsigned re
FLAC__ASSERT(pattern != 0);
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(rep = 0; rep < reps; rep++) {
@@ -321,7 +315,7 @@ static FLAC__bool generate_fsd16(const char *fn, const int pattern[], unsigned r
FLAC__ASSERT(pattern != 0);
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(rep = 0; rep < reps; rep++) {
@@ -345,7 +339,7 @@ static FLAC__bool generate_wbps16(const char *fn, unsigned samples)
FILE *f;
unsigned sample;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(sample = 0; sample < samples; sample++) {
@@ -372,7 +366,7 @@ static FLAC__bool generate_fsd24(const char *fn, const int pattern[], unsigned r
FLAC__ASSERT(pattern != 0);
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(rep = 0; rep < reps; rep++) {
@@ -400,7 +394,7 @@ static FLAC__bool generate_sine8_1(const char *fn, const double sample_rate, con
double theta1, theta2;
unsigned i;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -427,7 +421,7 @@ static FLAC__bool generate_sine8_2(const char *fn, const double sample_rate, con
double theta1, theta2;
unsigned i;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -458,7 +452,7 @@ static FLAC__bool generate_sine16_1(const char *fn, const double sample_rate, co
double theta1, theta2;
unsigned i;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -485,7 +479,7 @@ static FLAC__bool generate_sine16_2(const char *fn, const double sample_rate, co
double theta1, theta2;
unsigned i;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -516,7 +510,7 @@ static FLAC__bool generate_sine24_1(const char *fn, const double sample_rate, co
double theta1, theta2;
unsigned i;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -543,7 +537,7 @@ static FLAC__bool generate_sine24_2(const char *fn, const double sample_rate, co
double theta1, theta2;
unsigned i;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -569,7 +563,7 @@ static FLAC__bool generate_noise(const char *fn, unsigned bytes)
FILE *f;
unsigned b;
- if(0 == (f = fopen(fn, mode)))
+ if(0 == (f = fopen(fn, "wb")))
return false;
for(b = 0; b < bytes; b++) {
@@ -599,7 +593,7 @@ static FLAC__bool generate_raw(const char *filename, unsigned channels, unsigned
FILE *f;
unsigned i, j;
- if(0 == (f = fopen(filename, mode)))
+ if(0 == (f = fopen(filename, "wb")))
return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
@@ -632,7 +626,7 @@ static FLAC__bool generate_aiff(const char *filename, unsigned sample_rate, unsi
FILE *f;
unsigned i, j;
- if(0 == (f = fopen(filename, mode)))
+ if(0 == (f = fopen(filename, "wb")))
return false;
if(fwrite("FORM", 1, 4, f) < 4)
goto foo;
@@ -693,7 +687,7 @@ static FLAC__bool generate_wav(const char *filename, unsigned sample_rate, unsig
FILE *f;
unsigned i, j;
- if(0 == (f = fopen(filename, mode)))
+ if(0 == (f = fopen(filename, "wb")))
return false;
if(fwrite("RIFF", 1, 4, f) < 4)
goto foo;
@@ -768,14 +762,14 @@ static FLAC__bool generate_wackywavs(void)
4, 0, 0, 0, 'b', 'l', 'a', 'h'
};
- if(0 == (f = fopen("wacky1.wav", mode)))
+ if(0 == (f = fopen("wacky1.wav", "wb")))
return false;
if(fwrite(wav, 1, 84, f) < 84)
goto foo;
fclose(f);
wav[4] += 12;
- if(0 == (f = fopen("wacky2.wav", mode)))
+ if(0 == (f = fopen("wacky2.wav", "wb")))
return false;
if(fwrite(wav, 1, 96, f) < 96)
goto foo;
diff --git a/src/OGG/framing.c b/src/OGG/framing.c
index 871d6917..0595b955 100644
--- a/src/OGG/framing.c
+++ b/src/OGG/framing.c
@@ -5,14 +5,14 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: code raw [Vorbis] packets into framed OggSquish stream and
decode Ogg streams back into raw packets
- last mod: $Id: framing.c 9601 2005-07-23 00:19:14Z giles $
+ last mod: $Id: framing.c 12446 2007-02-08 22:22:43Z xiphmont $
note: The CRC code is directly derived from public domain code by
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
@@ -268,8 +268,12 @@ void ogg_page_checksum_set(ogg_page *og){
}
/* submit data to the internal buffer of the framing engine */
-int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
- int lacing_vals=op->bytes/255+1,i;
+int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
+ long e_o_s, ogg_int64_t granulepos){
+
+ int bytes = 0, lacing_vals, i;
+ for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
+ lacing_vals=bytes/255+1;
if(os->body_returned){
/* advance packet data according to the body_returned pointer. We
@@ -284,7 +288,7 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
}
/* make sure we have the buffer storage */
- _os_body_expand(os,op->bytes);
+ _os_body_expand(os,bytes);
_os_lacing_expand(os,lacing_vals);
/* Copy in the submitted packet. Yes, the copy is a waste; this is
@@ -292,16 +296,18 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
will actually be fairly easy to eliminate the extra copy in the
future */
- memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
- os->body_fill+=op->bytes;
+ for (i = 0; i < count; ++i) {
+ memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len);
+ os->body_fill += (int)iov[i].iov_len;
+ }
/* Store lacing vals for this packet */
for(i=0;ilacing_vals[os->lacing_fill+i]=255;
os->granule_vals[os->lacing_fill+i]=os->granulepos;
}
- os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
- os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
+ os->lacing_vals[os->lacing_fill+i]=bytes%255;
+ os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
/* flag the first segment as the beginning of the packet */
os->lacing_vals[os->lacing_fill]|= 0x100;
@@ -311,11 +317,18 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
/* for the sake of completeness */
os->packetno++;
- if(op->e_o_s)os->e_o_s=1;
+ if(e_o_s)os->e_o_s=1;
return(0);
}
+int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
+ ogg_iovec_t iov;
+ iov.iov_base = op->packet;
+ iov.iov_len = op->bytes;
+ return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos);
+}
+
/* This will flush remaining packets into a page (returning nonzero),
even if there is not enough data to trigger a flush normally
(undersized page). If there are no packets or partial packets to
@@ -624,7 +637,7 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
if(!next)
next=oy->data+oy->fill;
- oy->returned=next-oy->data;
+ oy->returned=(int)(next-oy->data);
return(-(next-outerpage));
}
diff --git a/src/OGG/include/ogg/ogg.h b/src/OGG/include/ogg/ogg.h
index 9082679d..1558290c 100644
--- a/src/OGG/include/ogg/ogg.h
+++ b/src/OGG/include/ogg/ogg.h
@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: toplevel libogg include
- last mod: $Id: ogg.h 7188 2004-07-20 07:26:04Z xiphmont $
+ last mod: $Id: ogg.h 12446 2007-02-08 22:22:43Z xiphmont $
********************************************************************/
#ifndef _OGG_H
@@ -23,6 +23,11 @@ extern "C" {
#include
+typedef struct {
+ void *iov_base;
+ size_t iov_len;
+} ogg_iovec_t;
+
typedef struct {
long endbyte;
int endbit;
@@ -148,6 +153,8 @@ extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
+ int count, long e_o_s, ogg_int64_t granulepos);
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
diff --git a/src/OGG/include/ogg/os_types.h b/src/OGG/include/ogg/os_types.h
index 32dcb8bf..8b7be672 100644
--- a/src/OGG/include/ogg/os_types.h
+++ b/src/OGG/include/ogg/os_types.h
@@ -11,7 +11,7 @@
********************************************************************
function: #ifdef jail to whip a few platforms into the UNIX ideal.
- last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $
+ last mod: $Id: os_types.h 11511 2006-06-03 22:30:13Z giles $
********************************************************************/
#ifndef _OS_TYPES_H
@@ -27,19 +27,20 @@
#if defined(_WIN32)
# if defined(__CYGWIN__)
-# include <_G_config.h>
- typedef _G_int64_t ogg_int64_t;
- typedef _G_int32_t ogg_int32_t;
- typedef _G_uint32_t ogg_uint32_t;
- typedef _G_int16_t ogg_int16_t;
- typedef _G_uint16_t ogg_uint16_t;
+# include
+ typedef int16_t ogg_int16_t;
+ typedef uint16_t ogg_uint16_t;
+ typedef int32_t ogg_int32_t;
+ typedef uint32_t ogg_uint32_t;
+ typedef int64_t ogg_int64_t;
+ typedef uint64_t ogg_uint64_t;
# elif defined(__MINGW32__)
- typedef short ogg_int16_t;
- typedef unsigned short ogg_uint16_t;
- typedef int ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef long long ogg_int64_t;
- typedef unsigned long long ogg_uint64_t;
+ typedef short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+ typedef int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long ogg_int64_t;
+ typedef unsigned long long ogg_uint64_t;
# elif defined(__MWERKS__)
typedef long long ogg_int64_t;
typedef int ogg_int32_t;
diff --git a/src/aiff.c b/src/aiff.c
index 63484772..81991b8f 100644
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -849,6 +849,14 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames),
&(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ;
+ if (comm_fmt->size > 0x10000 && (comm_fmt->size & 0xffff) == 0)
+ { psf_log_printf (psf, " COMM : %d (0x%x) *** should be ", comm_fmt->size, comm_fmt->size) ;
+ comm_fmt->size = ENDSWAP_INT (comm_fmt->size) ;
+ psf_log_printf (psf, "%d (0x%x)\n", comm_fmt->size, comm_fmt->size) ;
+ }
+ else
+ psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
+
if (comm_fmt->size == SIZEOF_AIFF_COMM)
comm_fmt->encoding = NONE_MARKER ;
else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN)
@@ -865,7 +873,6 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
psf->u.scbuf [encoding_len] = 0 ;
} ;
- psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
psf_log_printf (psf, " Sample Rate : %d\n", tenbytefloat2int (comm_fmt->sampleRate)) ;
psf_log_printf (psf, " Frames : %u%s\n", comm_fmt->numSampleFrames, (comm_fmt->numSampleFrames == 0 && psf->filelength > 104) ? " (Should not be 0)" : "") ;
psf_log_printf (psf, " Channels : %d\n", comm_fmt->numChannels) ;
diff --git a/src/au.c b/src/au.c
index 3a5f93bd..e5dac5fe 100644
--- a/src/au.c
+++ b/src/au.c
@@ -435,7 +435,12 @@ au_read_header (SF_PRIVATE *psf)
} ;
psf_log_printf (psf, " Sample Rate : %d\n", au_fmt.samplerate) ;
- psf_log_printf (psf, " Channels : %d\n", au_fmt.channels) ;
+ if (au_fmt.channels < 1)
+ { psf_log_printf (psf, " Channels : %d **** should be >= 1\n", au_fmt.channels) ;
+ return SFE_CHANNEL_COUNT_ZERO ;
+ }
+ else
+ psf_log_printf (psf, " Channels : %d\n", au_fmt.channels) ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
diff --git a/src/common.h b/src/common.h
index 11c907ac..775010fc 100644
--- a/src/common.h
+++ b/src/common.h
@@ -413,6 +413,7 @@ enum
SFE_INTERNAL,
SFE_BAD_CONTROL_CMD,
SFE_BAD_ENDIAN,
+ SFE_CHANNEL_COUNT_ZERO,
SFE_CHANNEL_COUNT,
SFE_BAD_RDWR_FORMAT,
@@ -523,12 +524,10 @@ enum
SFE_MAT4_BAD_NAME,
SFE_MAT4_NO_SAMPLERATE,
- SFE_MAT4_ZERO_CHANNELS,
SFE_MAT5_BAD_ENDIAN,
SFE_MAT5_NO_BLOCK,
SFE_MAT5_SAMPLE_RATE,
- SFE_MAT5_ZERO_CHANNELS,
SFE_PVF_NO_PVF1,
SFE_PVF_BAD_HEADER,
diff --git a/src/create_symbols_file.py b/src/create_symbols_file.py
index 8d60df81..27e78f54 100755
--- a/src/create_symbols_file.py
+++ b/src/create_symbols_file.py
@@ -69,7 +69,6 @@ ALL_SYMBOLS = (
( "sf_strerror", 50 ),
( "sf_get_string", 60 ),
( "sf_set_string", 61 ),
- ( "sf_get_info", 68 ),
( "sf_open_fd", 70 ),
( "sf_open_virtual", 80 ),
( "sf_write_sync", 90 )
diff --git a/src/flac.c b/src/flac.c
index 7771e55b..45310b8c 100644
--- a/src/flac.c
+++ b/src/flac.c
@@ -40,8 +40,7 @@
** Private static functions.
*/
-#define ENC_BUFFER_SIZE 4096
-#define RBUFFER_LEN 4096
+#define ENC_BUFFER_SIZE 8192
typedef enum
{ PFLAC_PCM_SHORT = 50,
@@ -170,6 +169,17 @@ flac_buffer_copy (SF_PRIVATE *psf)
const FLAC__int32* const *buffer = pflac->wbuffer ;
unsigned i = 0, j, offset ;
+ /*
+ ** frame->header.blocksize is variable and we're using a constant blocksize
+ ** of FLAC__MAX_BLOCK_SIZE.
+ ** Check our assumptions here.
+ */
+ if (frame->header.blocksize > FLAC__MAX_BLOCK_SIZE)
+ { psf_log_printf (psf, "Ooops : frame->header.blocksize (%d) > FLAC__MAX_BLOCK_SIZE (%d)\n", __func__, __LINE__, frame->header.blocksize, FLAC__MAX_BLOCK_SIZE) ;
+ psf->error = SFE_INTERNAL ;
+ return 0 ;
+ } ;
+
if (pflac->ptr == NULL)
{ /*
** Not sure why this code is here and not elsewhere.
@@ -177,17 +187,9 @@ flac_buffer_copy (SF_PRIVATE *psf)
*/
pflac->bufferbackup = SF_TRUE ;
for (i = 0 ; i < frame->header.channels ; i++)
- { /*
- ** frame->header.blocksize is variable so don't use it, use a
- ** constant and check it.
- */
- if (frame->header.blocksize > RBUFFER_LEN)
- { psf_log_printf (psf, "%s %d : frame->header.blocksize > RBUFFER_LEN\n", __func__, __LINE__) ;
- return 0 ;
- } ;
-
+ {
if (pflac->rbuffer [i] == NULL)
- pflac->rbuffer [i] = calloc (RBUFFER_LEN, sizeof (FLAC__int32)) ;
+ pflac->rbuffer [i] = calloc (FLAC__MAX_BLOCK_SIZE, sizeof (FLAC__int32)) ;
memcpy (pflac->rbuffer [i], buffer [i], frame->header.blocksize * sizeof (FLAC__int32)) ;
} ;
diff --git a/src/mat4.c b/src/mat4.c
index 3ead0328..f85f96de 100644
--- a/src/mat4.c
+++ b/src/mat4.c
@@ -276,7 +276,7 @@ mat4_read_header (SF_PRIVATE *psf)
if (rows == 0 && cols == 0)
{ psf_log_printf (psf, "*** Error : zero channel count.\n") ;
- return SFE_MAT4_ZERO_CHANNELS ;
+ return SFE_CHANNEL_COUNT_ZERO ;
} ;
psf->sf.channels = rows ;
diff --git a/src/mat5.c b/src/mat5.c
index ecd0039e..b4de610e 100644
--- a/src/mat5.c
+++ b/src/mat5.c
@@ -448,7 +448,7 @@ mat5_read_header (SF_PRIVATE *psf)
if (rows == 0 && cols == 0)
{ psf_log_printf (psf, "*** Error : zero channel count.\n") ;
- return SFE_MAT5_ZERO_CHANNELS ;
+ return SFE_CHANNEL_COUNT_ZERO ;
} ;
psf->sf.channels = rows ;
diff --git a/src/sndfile.c b/src/sndfile.c
index 2b34754f..9e372d54 100644
--- a/src/sndfile.c
+++ b/src/sndfile.c
@@ -96,6 +96,7 @@ ErrorStruct SndfileErrors [] =
{ SFE_INTERNAL , "Unspecified internal error." },
{ SFE_BAD_CONTROL_CMD , "Bad command passed to function sf_command()." },
{ SFE_BAD_ENDIAN , "Bad endian-ness. Try default endian-ness" },
+ { SFE_CHANNEL_COUNT_ZERO , "Channel count is zero." },
{ SFE_CHANNEL_COUNT , "Too many channels specified." },
{ SFE_BAD_SEEK , "Internal psf_fseek() failed." },
@@ -207,12 +208,10 @@ ErrorStruct SndfileErrors [] =
{ SFE_MAT4_BAD_NAME , "Error in MAT4 file. No variable name." },
{ SFE_MAT4_NO_SAMPLERATE , "Error in MAT4 file. No sample rate." },
- { SFE_MAT4_ZERO_CHANNELS , "Error in MAT4 file. Channel count is zero." },
{ SFE_MAT5_BAD_ENDIAN , "Error in MAT5 file. Not able to determine endian-ness." },
{ SFE_MAT5_NO_BLOCK , "Error in MAT5 file. Bad block structure." },
{ SFE_MAT5_SAMPLE_RATE , "Error in MAT5 file. Not able to determine sample rate." },
- { SFE_MAT5_ZERO_CHANNELS , "Error in MAT5 file. Channel count is zero." },
{ SFE_PVF_NO_PVF1 , "Error in PVF file. No PVF1 marker." },
{ SFE_PVF_BAD_HEADER , "Error in PVF file. Bad header." },
@@ -859,6 +858,12 @@ sf_command (SNDFILE *sndfile, int command, void *data, int datasize)
psf->norm_float = (datasize) ? SF_TRUE : SF_FALSE ;
return old_value ;
+ case SFC_GET_CURRENT_SF_INFO :
+ if (data == NULL || datasize != SIGNED_SIZEOF (SF_INFO))
+ return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+ memcpy (data, &psf->sf, sizeof (SF_INFO)) ;
+ break ;
+
case SFC_SET_NORM_DOUBLE :
old_value = psf->norm_double ;
psf->norm_double = (datasize) ? SF_TRUE : SF_FALSE ;
@@ -1240,23 +1245,6 @@ sf_seek (SNDFILE *sndfile, sf_count_t offset, int whence)
/*------------------------------------------------------------------------------
*/
-int
-sf_get_info (SNDFILE * sndfile, SF_INFO * info)
-{ SF_PRIVATE *psf ;
-
- if (info == NULL)
- return SF_FALSE ;
- if ((psf = (SF_PRIVATE*) sndfile) == NULL)
- return SF_FALSE ;
- if (psf->Magick != SNDFILE_MAGICK)
- return SF_FALSE ;
-
- /* Need to correct psf->sf.frames ???? */
- memcpy (info, &psf->sf, sizeof (SF_INFO)) ;
-
- return SF_TRUE ;
-} /* sf_get_info */
-
const char*
sf_get_string (SNDFILE *sndfile, int str_type)
{ SF_PRIVATE *psf ;
diff --git a/src/sndfile.h.in b/src/sndfile.h.in
index 6a130139..8ccb0045 100644
--- a/src/sndfile.h.in
+++ b/src/sndfile.h.in
@@ -30,14 +30,7 @@
#define SNDFILE_1
#include
-
-/* For the Metrowerks CodeWarrior Pro Compiler (mainly MacOS) */
-
-#if (defined (__MWERKS__))
-#include
-#else
-#include
-#endif
+#include
#ifdef __cplusplus
extern "C" {
@@ -128,6 +121,8 @@ enum
enum
{ SFC_GET_LIB_VERSION = 0x1000,
SFC_GET_LOG_INFO = 0x1001,
+ SFC_GET_CURRENT_SF_INFO = 0x1002,
+
SFC_GET_NORM_DOUBLE = 0x1010,
SFC_GET_NORM_FLOAT = 0x1011,
@@ -290,14 +285,20 @@ enum
typedef struct SNDFILE_tag SNDFILE ;
-/* The following typedef is system specific and is defined when libsndfile is.
-** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD),
-** off64_t (Solaris), __int64_t (Win32) etc.
+/* The following typedef is system specific and is defined when libsndfile is
+** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t
+** (Solaris), __int64_t (Win32) etc. On windows, we need to allow the same
+** header file to be compiler by both GCC and the microsoft compiler.
*/
+#ifdef _MSCVER
+typedef __int64_t sf_count_t ;
+#define SF_COUNT_MAX 0x7fffffffffffffffi64
+#else
typedef @TYPEOF_SF_COUNT_T@ sf_count_t ;
-
#define SF_COUNT_MAX @SF_COUNT_MAX@
+#endif
+
/* A pointer to a SF_INFO structure is passed to sf_open_read () and filled in.
** On write, the SF_INFO structure is filled in by the user and passed into
@@ -521,12 +522,6 @@ int sf_format_check (const SF_INFO *info) ;
sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ;
-/* Retrieve the SF_INFO struct for the given SNDFILE. Returns SF_FALSE on
-** failure, SF_TRUE otherwise.
-*/
-
-int sf_get_info (SNDFILE * sndfile, SF_INFO * info) ;
-
/* Functions for retrieving and setting string data within sound files.
** Not all file types support this features; AIFF and WAV do. For both
** functions, the str_type parameter must be one of the SF_STR_* values
diff --git a/src/voc.c b/src/voc.c
index de7abf2f..6948a236 100644
--- a/src/voc.c
+++ b/src/voc.c
@@ -199,20 +199,26 @@ voc_read_header (SF_PRIVATE *psf)
psf->endian = SF_ENDIAN_LITTLE ;
while (1)
- { offset += psf_binheader_readf (psf, "1", &block_type) ;
+ { int size ;
+ short count ;
+
+ block_type = 0 ;
+ offset += psf_binheader_readf (psf, "1", &block_type) ;
switch (block_type)
{ case VOC_ASCII :
- { int size ;
+ offset += psf_binheader_readf (psf, "e3", &size) ;
- offset += psf_binheader_readf (psf, "e3", &size) ;
+ psf_log_printf (psf, " ASCII : %d\n", size) ;
- psf_log_printf (psf, " ASCII : %d\n", size) ;
+ offset += psf_binheader_readf (psf, "b", psf->header, size) ;
+ psf->header [size] = 0 ;
+ psf_log_printf (psf, " text : %s\n", psf->header) ;
+ continue ;
- offset += psf_binheader_readf (psf, "b", psf->header, size) ;
- psf->header [size] = 0 ;
- psf_log_printf (psf, " text : %s\n", psf->header) ;
- } ;
+ case VOC_REPEAT :
+ offset += psf_binheader_readf (psf, "e32", &size, &count) ;
+ psf_log_printf (psf, " Repeat : %d\n", count) ;
continue ;
case VOC_SOUND_DATA :
@@ -242,7 +248,7 @@ voc_read_header (SF_PRIVATE *psf)
psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
return SFE_VOC_BAD_SECTIONS ;
}
- else if (offset + size - 1 < psf->filelength)
+ else if (psf->filelength - offset - size > 4)
{ psf_log_printf (psf, "Seems to be a multi-segment file (#1).\n") ;
psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
return SFE_VOC_BAD_SECTIONS ;
@@ -869,10 +875,3 @@ BLOCK 9 - data block that supersedes blocks 1 and 8.
Data is stored left, right
------------------------------------------------------------------------*/
-/*
-** Do not edit or modify anything in this comment block.
-** The arch-tag line is a file identity tag for the GNU Arch
-** revision control system.
-**
-** arch-tag: 40a50167-a81c-463a-9e1d-3282ff84e09d
-*/
diff --git a/src/w64.c b/src/w64.c
index 1fd7ddea..73ab00d3 100644
--- a/src/w64.c
+++ b/src/w64.c
@@ -226,7 +226,7 @@ w64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ;
- if (psf->filelength < chunk_size)
+ if (psf->filelength != chunk_size)
psf_log_printf (psf, "riff : %D (should be %D)\n", chunk_size, psf->filelength) ;
else
psf_log_printf (psf, "riff : %D\n", chunk_size) ;
@@ -399,7 +399,7 @@ w64_write_header (SF_PRIVATE *psf, int calc_length)
psf_fseek (psf, 0, SEEK_SET) ;
/* riff marker, length, wave and 'fmt ' markers. */
- psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength - 8, wave_MARKER16, fmt_MARKER16) ;
+ psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength, wave_MARKER16, fmt_MARKER16) ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
diff --git a/src/wav.c b/src/wav.c
index 01d97dbe..cbe48b3a 100644
--- a/src/wav.c
+++ b/src/wav.c
@@ -65,6 +65,15 @@
#define elmo_MARKER (MAKE_MARKER ('e', 'l', 'm', 'o'))
#define cart_MARKER (MAKE_MARKER ('c', 'a', 'r', 't'))
+#define exif_MARKER (MAKE_MARKER ('e', 'x', 'i', 'f'))
+#define ever_MARKER (MAKE_MARKER ('e', 'v', 'e', 'r'))
+#define etim_MARKER (MAKE_MARKER ('e', 't', 'i', 'm'))
+#define ecor_MARKER (MAKE_MARKER ('e', 'c', 'o', 'r'))
+#define emdl_MARKER (MAKE_MARKER ('e', 'm', 'd', 'l'))
+#define emnt_MARKER (MAKE_MARKER ('e', 'm', 'n', 't'))
+#define erel_MARKER (MAKE_MARKER ('e', 'r', 'e', 'l'))
+#define eucm_MARKER (MAKE_MARKER ('e', 'u', 'c', 'm'))
+
#define ISFT_MARKER (MAKE_MARKER ('I', 'S', 'F', 'T'))
#define ICRD_MARKER (MAKE_MARKER ('I', 'C', 'R', 'D'))
#define ICOP_MARKER (MAKE_MARKER ('I', 'C', 'O', 'P'))
@@ -155,6 +164,7 @@ static int wav_command (SF_PRIVATE *psf, int command, void *data, int datasize)
static int wav_close (SF_PRIVATE *psf) ;
static int wav_subchunk_parse (SF_PRIVATE *psf, int chunk) ;
+static int exif_subchunk_parse (SF_PRIVATE *psf, unsigned int length) ;
static int wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
static int wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
static int wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
@@ -1286,7 +1296,7 @@ wav_subchunk_parse (SF_PRIVATE *psf, int chunk)
psf_log_printf (psf, " %M\n", chunk) ;
break ;
- case data_MARKER:
+ case data_MARKER :
psf_log_printf (psf, " %M inside a LIST block??? Backing out.\n", chunk) ;
/* Jump back four bytes and return to caller. */
psf_binheader_readf (psf, "j", -4) ;
@@ -1353,6 +1363,11 @@ wav_subchunk_parse (SF_PRIVATE *psf, int chunk)
psf_log_printf (psf, " %M : %d\n", chunk, dword) ;
break ;
+ case exif_MARKER :
+ psf_log_printf (psf, " %M\n", chunk) ;
+ bytesread += exif_subchunk_parse (psf, length - bytesread) ;
+ break ;
+
default :
psf_binheader_readf (psf, "4", &dword) ;
bytesread += sizeof (dword) ;
@@ -1598,7 +1613,7 @@ wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen)
return 0 ;
} /* wav_read_acid_chunk */
-int
+static int
wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize)
{
SF_BROADCAST_INFO* b ;
@@ -1667,10 +1682,81 @@ wav_write_bext_chunk (SF_PRIVATE *psf)
return 0 ;
} /* wav_write_bext_chunk */
+static int
+exif_fill_and_sink (SF_PRIVATE *psf, char* buf, size_t bufsz, size_t toread)
+{
+ size_t bytesread = 0 ;
+
+ buf [0] = 0 ;
+ bufsz -= 1 ;
+ if (toread < bufsz)
+ bufsz = toread ;
+ bytesread = psf_binheader_readf (psf, "b", buf, bufsz) ;
+ buf [bufsz] = 0 ;
+
+ if (bytesread == bufsz && toread > bufsz)
+ bytesread += psf_binheader_readf (psf, "j", toread - bufsz) ;
+
+ return bytesread ;
+} /* exif_fill_and_sink */
+
/*
-** Do not edit or modify anything in this comment block.
-** The arch-tag line is a file identity tag for the GNU Arch
-** revision control system.
-**
-** arch-tag: 9c551689-a1d8-4905-9f56-26a204374f18
+** Exif specification for audio files, at JEITA CP-3451 Exif 2.2 section 5
+** (Exif Audio File Specification) http://www.exif.org/Exif2-2.PDF
*/
+static int
+exif_subchunk_parse (SF_PRIVATE *psf, unsigned int length)
+{
+ unsigned marker, dword, vmajor = -1, vminor = -1, bytesread = 0 ;
+ char buf [4096] ;
+
+ while (bytesread < length)
+ {
+ bytesread += psf_binheader_readf (psf, "m", &marker) ;
+
+ switch (marker)
+ {
+ case 0 : /* camera padding? */
+ break ;
+
+ case ever_MARKER :
+ bytesread += psf_binheader_readf (psf, "j4", 4, &dword) ;
+ vmajor = 10 * (((dword >> 24) & 0xff) - '0') + (((dword >> 16) & 0xff) - '0') ;
+ vminor = 10 * (((dword >> 8) & 0xff) - '0') + ((dword & 0xff) - '0') ;
+ psf_log_printf (psf, " EXIF Version : %u.%02u\n", vmajor, vminor) ;
+ break ;
+
+ case emnt_MARKER : /* design information: null-terminated string */
+ case emdl_MARKER : /* model name ; null-terminated string */
+ case ecor_MARKER : /* manufacturer: null-terminated string */
+ case etim_MARKER : /* creation time: null-terminated string in the format "hour:minute:second.subsecond" */
+ case erel_MARKER : /* relation info: null-terminated string (filename) */
+ case eucm_MARKER : /* user comment: 4-byte size follows, then possibly unicode data */
+ psf_binheader_readf (psf, "4", &dword) ;
+ bytesread += sizeof (dword) ;
+ dword += (dword & 1) ;
+
+ bytesread += exif_fill_and_sink (psf, buf, sizeof (buf), dword) ;
+
+ /* BAD - don't know what's going on here -- maybe a bug in the camera */
+ /* field should be NULL-terminated but there's no room for it with the reported number */
+ /* example output: emdl : 8 (EX-Z1050) */
+ if (marker == emdl_MARKER && dword == strlen (buf) /* should be >= strlen+1*/)
+ { psf_log_printf (psf, " *** field size too small for string (sinking 2 bytes)\n") ;
+ bytesread += psf_binheader_readf (psf, "j", 2) ;
+ } ;
+
+ psf_log_printf (psf, " %M : %d (%s)\n", marker, dword, buf) ;
+ if (dword > length)
+ return bytesread ;
+ break ;
+
+ default :
+ psf_log_printf (psf, " *** %M (%d): -- ignored --\n", marker, marker) ;
+ break ;
+ } ;
+ } ;
+
+ return bytesread ;
+} /* exif_subchunk_parse */
+
diff --git a/tests/benchmark-1.0.18pre16-hendrix b/tests/benchmark-1.0.18pre16-hendrix
new file mode 100644
index 00000000..951bc56d
--- /dev/null
+++ b/tests/benchmark-1.0.18pre16-hendrix
@@ -0,0 +1,38 @@
+Benchmarking libsndfile-1.0.18pre15
+-----------------------------------
+Each test takes a little over 5 seconds.
+
+ Raw write PCM_16 : 103189885 samples per sec
+ Raw read PCM_16 : 660854036 samples per sec
+
+Native endian I/O :
+ Write short to PCM_16 : 95.08% of raw write
+ Read short from PCM_16 : 96.39% of raw read
+ Write int to PCM_24 : 54.55% of raw write
+ Read int from PCM_24 : 28.50% of raw read
+ Write int to PCM_32 : 46.97% of raw write
+ Read int from PCM_32 : 39.98% of raw read
+ Write float to PCM_16 : 60.85% of raw write
+ Read float from PCM_16 : 27.79% of raw read
+ Write float to PCM_24 : 46.23% of raw write
+ Read float from PCM_24 : 22.62% of raw read
+ Write float to PCM_32 : 35.38% of raw write
+ Read float from PCM_32 : 24.18% of raw read
+ Write float to FLOAT : 47.73% of raw write
+ Read float from FLOAT : 40.62% of raw read
+
+Endian swapped I/O :
+ Write short to PCM_16 : 79.98% of raw write
+ Read short from PCM_16 : 49.27% of raw read
+ Write int to PCM_24 : 53.80% of raw write
+ Read int from PCM_24 : 28.50% of raw read
+ Write int to PCM_32 : 41.68% of raw write
+ Read int from PCM_32 : 25.89% of raw read
+ Write float to PCM_16 : 61.03% of raw write
+ Read float from PCM_16 : 27.74% of raw read
+ Write float to PCM_24 : 45.10% of raw write
+ Read float from PCM_24 : 22.43% of raw read
+ Write float to PCM_32 : 35.24% of raw write
+ Read float from PCM_32 : 22.37% of raw read
+ Write float to FLOAT : 42.01% of raw write
+ Read float from FLOAT : 28.98% of raw read
diff --git a/tests/benchmark-1.0.18pre16-mingus b/tests/benchmark-1.0.18pre16-mingus
new file mode 100644
index 00000000..fa0584e1
--- /dev/null
+++ b/tests/benchmark-1.0.18pre16-mingus
@@ -0,0 +1,38 @@
+Benchmarking libsndfile-1.0.18pre15
+-----------------------------------
+Each test takes a little over 5 seconds.
+
+ Raw write PCM_16 : 178237074 samples per sec
+ Raw read PCM_16 : 368885269 samples per sec
+
+Native endian I/O :
+ Write short to PCM_16 : 98.84% of raw write
+ Read short from PCM_16 : 147.10% of raw read
+ Write int to PCM_24 : 33.74% of raw write
+ Read int from PCM_24 : 30.82% of raw read
+ Write int to PCM_32 : 48.34% of raw write
+ Read int from PCM_32 : 62.43% of raw read
+ Write float to PCM_16 : 41.86% of raw write
+ Read float from PCM_16 : 36.73% of raw read
+ Write float to PCM_24 : 28.38% of raw write
+ Read float from PCM_24 : 19.50% of raw read
+ Write float to PCM_32 : 23.68% of raw write
+ Read float from PCM_32 : 28.76% of raw read
+ Write float to FLOAT : 47.21% of raw write
+ Read float from FLOAT : 60.85% of raw read
+
+Endian swapped I/O :
+ Write short to PCM_16 : 54.94% of raw write
+ Read short from PCM_16 : 59.03% of raw read
+ Write int to PCM_24 : 33.40% of raw write
+ Read int from PCM_24 : 31.98% of raw read
+ Write int to PCM_32 : 30.89% of raw write
+ Read int from PCM_32 : 33.68% of raw read
+ Write float to PCM_16 : 41.61% of raw write
+ Read float from PCM_16 : 26.76% of raw read
+ Write float to PCM_24 : 25.75% of raw write
+ Read float from PCM_24 : 19.84% of raw read
+ Write float to PCM_32 : 21.29% of raw write
+ Read float from PCM_32 : 21.78% of raw read
+ Write float to FLOAT : 30.82% of raw write
+ Read float from FLOAT : 35.04% of raw read
diff --git a/tests/command_test.c b/tests/command_test.c
index 357a713f..a687928b 100644
--- a/tests/command_test.c
+++ b/tests/command_test.c
@@ -36,14 +36,15 @@
#define BUFFER_LEN (1<<10)
#define LOG_BUFFER_SIZE 1024
-static void float_norm_test (const char *filename) ;
-static void double_norm_test (const char *filename) ;
-static void format_tests (void) ;
-static void calc_peak_test (int filetype, const char *filename) ;
-static void truncate_test (const char *filename, int filetype) ;
-static void instrument_test (const char *filename, int filetype) ;
-static void channel_map_test (const char *filename, int filetype) ;
-static void broadcast_test (const char *filename, int filetype) ;
+static void float_norm_test (const char *filename) ;
+static void double_norm_test (const char *filename) ;
+static void format_tests (void) ;
+static void calc_peak_test (int filetype, const char *filename) ;
+static void truncate_test (const char *filename, int filetype) ;
+static void instrument_test (const char *filename, int filetype) ;
+static void channel_map_test (const char *filename, int filetype) ;
+static void broadcast_test (const char *filename, int filetype) ;
+static void current_sf_info_test (const char *filename) ;
/* Force the start of this buffer to be double aligned. Sparc-solaris will
** choke if its not.
@@ -130,6 +131,11 @@ main (int argc, char *argv [])
test_count++ ;
} ;
+ if (do_all || strcmp (argv [1], "current_sf_info") == 0)
+ { current_sf_info_test ("current.wav") ;
+ test_count++ ;
+ } ;
+
if (test_count == 0)
{ printf ("Mono : ************************************\n") ;
printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
@@ -870,11 +876,52 @@ channel_map_test (const char *filename, int filetype)
puts ("ok") ;
} /* channel_map_test */
+static void
+current_sf_info_test (const char *filename)
+{ SNDFILE *outfile, *infile ;
+ SF_INFO outinfo, ininfo ;
+ sf_count_t last_count ;
+
+ print_test_name ("current_sf_info_test", filename) ;
+
+ outinfo.samplerate = 44100 ;
+ outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
+ outinfo.channels = 1 ;
+ outinfo.frames = 0 ;
+
+ outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ;
+ sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ;
+
+ exit_if_true (outinfo.frames != 0,
+ "\n\nLine %d : Initial sfinfo.frames is not zero.\n\n", __LINE__
+ ) ;
+
+ test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ;
+ sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ;
+
+ exit_if_true (outinfo.frames != BUFFER_LEN,
+ "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__,
+ SF_COUNT_TO_LONG (outinfo.frames), BUFFER_LEN
+ ) ;
+
+ /* Read file making sure no channel map exists. */
+ infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ;
+
+ last_count = ininfo.frames ;
+
+ test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ;
+
+ sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ;
+
+ exit_if_true (ininfo.frames != BUFFER_LEN,
+ "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__,
+ SF_COUNT_TO_LONG (ininfo.frames), BUFFER_LEN
+ ) ;
+
+ sf_close (outfile) ;
+ sf_close (infile) ;
+
+ unlink (filename) ;
+ puts ("ok") ;
+} /* current_sf_info_test */
-/*
-** Do not edit or modify anything in this comment block.
-** The following line is a file identity tag for the GNU Arch
-** revision control system.
-**
-** arch-tag: 59e5d452-8dae-45aa-99aa-b78dc0deba1c
-*/
diff --git a/tests/dft_cmp.c b/tests/dft_cmp.c
index cf803385..09011d18 100644
--- a/tests/dft_cmp.c
+++ b/tests/dft_cmp.c
@@ -30,25 +30,49 @@
#define DFT_SPEC_LENGTH (DFT_DATA_LENGTH / 2)
static void dft_magnitude (const double *data, double *spectrum) ;
-static double calc_max_spectral_difference (double *spec1, double *spec2) ;
+static double calc_max_spectral_difference (const double *spec1, const double *spec2) ;
/*--------------------------------------------------------------------------------
** Public functions.
*/
double
-dft_cmp (int linenum, double *orig, double *test, int len, double target_snr, int allow_exit)
+dft_cmp_float (int linenum, const float *in_data, const float *test_data, int len, double target_snr, int allow_exit)
+{ static double orig [DFT_DATA_LENGTH] ;
+ static double test [DFT_DATA_LENGTH] ;
+ unsigned k ;
+
+ if (! orig || ! test)
+ { printf ("Error (line %d) : dft_cmp_float : Bad input arrays.\n", linenum) ;
+ return 1 ;
+ } ;
+
+ if (len != DFT_DATA_LENGTH)
+ { printf ("Error (line %d) : dft_cmp_float : Bad input array length.\n", linenum) ;
+ return 1 ;
+ } ;
+
+ for (k = 0 ; k < ARRAY_LEN (orig) ; k++)
+ { test [k] = test_data [k] ;
+ orig [k] = in_data [k] ;
+ } ;
+
+ return dft_cmp_double (linenum, orig, test, len, target_snr, allow_exit) ;
+} /* dft_cmp_float */
+
+double
+dft_cmp_double (int linenum, const double *orig, const double *test, int len, double target_snr, int allow_exit)
{ static double orig_spec [DFT_SPEC_LENGTH] ;
static double test_spec [DFT_SPEC_LENGTH] ;
double snr ;
if (! orig || ! test)
- { printf ("Error (line % d) : dft_cmp : Bad input arrays.\n", linenum) ;
+ { printf ("Error (line %d) : dft_cmp_double : Bad input arrays.\n", linenum) ;
return 1 ;
} ;
if (len != DFT_DATA_LENGTH)
- { printf ("Error (line % d) : dft_cmp : Bad input array length.\n", linenum) ;
+ { printf ("Error (line %d) : dft_cmp_double : Bad input array length.\n", linenum) ;
return 1 ;
} ;
@@ -68,7 +92,7 @@ dft_cmp (int linenum, double *orig, double *test, int len, double target_snr, in
snr = -500.0 ;
return snr ;
-} /* dft_cmp */
+} /* dft_cmp_double */
/*--------------------------------------------------------------------------------
** Quick dirty calculation of magnitude spectrum for real valued data using
@@ -112,7 +136,7 @@ dft_magnitude (const double *data, double *spectrum)
} /* dft_magnitude */
static double
-calc_max_spectral_difference (double *orig, double *test)
+calc_max_spectral_difference (const double *orig, const double *test)
{ double orig_max = 0.0, max_diff = 0.0 ;
int k ;
@@ -128,10 +152,3 @@ calc_max_spectral_difference (double *orig, double *test)
return 20.0 * log10 (max_diff / orig_max) ;
} /* calc_max_spectral_difference */
-/*
-** Do not edit or modify anything in this comment block.
-** The arch-tag line is a file identity tag for the GNU Arch
-** revision control system.
-**
-** arch-tag: cba7ffe2-bafe-44bd-b57a-15def3408410
-*/
diff --git a/tests/dft_cmp.h b/tests/dft_cmp.h
index 1fb63c5c..b3d4ca1c 100644
--- a/tests/dft_cmp.h
+++ b/tests/dft_cmp.h
@@ -1,30 +1,25 @@
/*
** Copyright (C) 2002-2004 Erik de Castro Lopo
-**
+**
** 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
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define DFT_DATA_LENGTH (2048)
-double dft_cmp (int linenum, double *orig, double *test, int len, double tolerance, int allow_exit) ;
+double dft_cmp_float (int linenum, const float *orig, const float *test, int len, double tolerance, int allow_exit) ;
+
+double dft_cmp_double (int linenum, const double *orig, const double *test, int len, double tolerance, int allow_exit) ;
-/*
-** Do not edit or modify anything in this comment block.
-** The arch-tag line is a file identity tag for the GNU Arch
-** revision control system.
-**
-** arch-tag: 10eac7b2-04ef-4d86-b7c0-8f1de57b12a0
-*/
diff --git a/tests/floating_point_test.tpl b/tests/floating_point_test.tpl
index 91ac68c7..16cedc07 100644
--- a/tests/floating_point_test.tpl
+++ b/tests/floating_point_test.tpl
@@ -40,15 +40,17 @@
static void float_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ;
static void double_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ;
-[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+]static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename) ;
-[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
+[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
+]
static double double_data [DFT_DATA_LENGTH] ;
-static double test_data [DFT_DATA_LENGTH] ;
+static double double_test [DFT_DATA_LENGTH] ;
static float float_data [DFT_DATA_LENGTH] ;
+static float float_test [DFT_DATA_LENGTH] ;
+
static double double_data [DFT_DATA_LENGTH] ;
static short short_data [DFT_DATA_LENGTH] ;
static int int_data [DFT_DATA_LENGTH] ;
@@ -162,9 +164,9 @@ main (int argc, char *argv [])
putchar ('\n') ;
/* Float int tests. */
-[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+] [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +].au") ;
-[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
+[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
+]
return 0 ;
@@ -176,20 +178,13 @@ main (int argc, char *argv [])
static void
float_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr)
-{ static float float_orig [DFT_DATA_LENGTH] ;
- static float float_test [DFT_DATA_LENGTH] ;
-
- SNDFILE *file ;
+{ SNDFILE *file ;
SF_INFO sfinfo ;
- int k ;
double snr ;
print_test_name ("float_scaled_test", filename) ;
- gen_windowed_sine_double (double_data, DFT_DATA_LENGTH, 1.0) ;
-
- for (k = 0 ; k < DFT_DATA_LENGTH ; k++)
- float_orig [k] = double_data [k] ;
+ gen_windowed_sine_float (float_data, DFT_DATA_LENGTH, 1.0) ;
sfinfo.samplerate = SAMPLE_RATE ;
sfinfo.frames = DFT_DATA_LENGTH ;
@@ -199,7 +194,7 @@ float_scaled_test (const char *filename, int allow_exit, int replace_float, int
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
- test_write_float_or_die (file, 0, float_orig, DFT_DATA_LENGTH, __LINE__) ;
+ test_write_float_or_die (file, 0, float_data, DFT_DATA_LENGTH, __LINE__) ;
sf_close (file) ;
@@ -218,10 +213,7 @@ float_scaled_test (const char *filename, int allow_exit, int replace_float, int
sf_close (file) ;
- for (k = 0 ; k < DFT_DATA_LENGTH ; k++)
- test_data [k] = float_test [k] ;
-
- snr = dft_cmp (__LINE__, double_data, test_data, DFT_DATA_LENGTH, target_snr, allow_exit) ;
+ snr = dft_cmp_float (__LINE__, float_data, float_test, DFT_DATA_LENGTH, target_snr, allow_exit) ;
exit_if_true (snr > target_snr, "% 6.1fdB SNR\n\n Error : should be better than % 6.1fdB\n\n", snr, target_snr) ;
@@ -254,7 +246,7 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int
sf_close (file) ;
- memset (test_data, 0, sizeof (test_data)) ;
+ memset (double_test, 0, sizeof (double_test)) ;
file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
@@ -265,11 +257,11 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int
check_log_buffer_or_die (file, __LINE__) ;
- test_read_double_or_die (file, 0, test_data, DFT_DATA_LENGTH, __LINE__) ;
+ test_read_double_or_die (file, 0, double_test, DFT_DATA_LENGTH, __LINE__) ;
sf_close (file) ;
- snr = dft_cmp (__LINE__, double_data, test_data, DFT_DATA_LENGTH, target_snr, allow_exit) ;
+ snr = dft_cmp_double (__LINE__, double_data, double_test, DFT_DATA_LENGTH, target_snr, allow_exit) ;
exit_if_true (snr > target_snr, "% 6.1fdB SNR\n\n Error : should be better than % 6.1fdB\n\n", snr, target_snr) ;
@@ -283,7 +275,7 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int
/*==============================================================================
*/
-[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+]
static void
[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename)
diff --git a/tests/utils.tpl b/tests/utils.tpl
index d7228681..06f607e6 100644
--- a/tests/utils.tpl
+++ b/tests/utils.tpl
@@ -74,7 +74,7 @@ exit_if_true (int test, const char *format, ...)
*/
[+ FOR io_type
-+]int oct_save_[+ (get "io_element") +] ([+ (get "io_element") +] *a, [+ (get "io_element") +] *b, int len) ;
++]int oct_save_[+ (get "io_element") +] (const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len) ;
[+ ENDFOR io_type
+]
@@ -261,7 +261,7 @@ static char octfilename [] = "error.dat" ;
[+ FOR io_type
+]int
-oct_save_[+ (get "io_element") +] ([+ (get "io_element") +] *a, [+ (get "io_element") +] *b, int len)
+oct_save_[+ (get "io_element") +] (const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len)
{ FILE *file ;
int k ;