[LIBMPG123]
authorThomas Faber <thomas.faber@reactos.org>
Sun, 18 Jun 2017 14:03:50 +0000 (14:03 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 18 Jun 2017 14:03:50 +0000 (14:03 +0000)
- Update to version 1.25.0
CORE-13451

svn path=/trunk/; revision=75093

14 files changed:
reactos/dll/win32/winemp3.acm/CMakeLists.txt
reactos/sdk/include/reactos/libs/libmpg123/compat.h
reactos/sdk/include/reactos/libs/libmpg123/mangle.h
reactos/sdk/include/reactos/libs/libmpg123/sample.h
reactos/sdk/include/reactos/libs/libmpg123/synth_sse3d.h
reactos/sdk/lib/3rdparty/libmpg123/CMakeLists.txt
reactos/sdk/lib/3rdparty/libmpg123/compat/compat.c
reactos/sdk/lib/3rdparty/libmpg123/compat/compat_impl.h [deleted file]
reactos/sdk/lib/3rdparty/libmpg123/compat/compat_str.c [new file with mode: 0644]
reactos/sdk/lib/3rdparty/libmpg123/icy2utf8.c
reactos/sdk/lib/3rdparty/libmpg123/id3.c
reactos/sdk/lib/3rdparty/libmpg123/libmpg123.c
reactos/sdk/lib/3rdparty/libmpg123/readers.c
reactos/sdk/lib/3rdparty/libmpg123/synth.c

index 241be69..3ad86b6 100644 (file)
@@ -16,5 +16,5 @@ add_library(winemp3.acm SHARED
 set_module_type(winemp3.acm win32dll)
 set_target_properties(winemp3.acm PROPERTIES SUFFIX "")
 target_link_libraries(winemp3.acm wine libmpg123 oldnames)
-add_importlibs(winemp3.acm winmm user32 msvcrt kernel32 ntdll)
+add_importlibs(winemp3.acm shlwapi winmm user32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET winemp3.acm DESTINATION reactos/system32 FOR all)
index 3cbc60d..74e0bdd 100644 (file)
 #define MPG123_COMPAT_H
 
 #include "config.h"
+#include "intsym.h"
 
-/* Needed for strdup(), in strict mode ... */
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 500
+/* For --nagging compilation with -std=c89, we need
+   to disable the inline keyword. */
+#ifdef PLAIN_C89
+#ifndef inline
+#define inline
+#endif
 #endif
 
 #include <errno.h>
 typedef unsigned char byte;
 
 #ifndef __REACTOS__
-#ifdef _MSC_VER
-typedef long ssize_t;
+#if defined(_MSC_VER) && !defined(MPG123_DEF_SSIZE_T)
+#define MPG123_DEF_SSIZE_T
+#include <stddef.h>
+typedef ptrdiff_t ssize_t;
 #endif
 #endif /* __REACTOS__ */
 
@@ -109,9 +115,9 @@ void *safe_realloc(void *ptr, size_t size);
 const char *strerror(int errnum);
 #endif
 
-#ifndef HAVE_STRDUP
-char *strdup(const char *s);
-#endif
+/* Roll our own strdup() that does not depend on libc feature test macros
+   and returns NULL on NULL input instead of crashing. */
+char* compat_strdup(const char *s);
 
 /* If we have the size checks enabled, try to derive some sane printfs.
    Simple start: Use max integer type and format if long is not big enough.
@@ -140,6 +146,10 @@ typedef intmax_t ssize_p;
 typedef long ssize_p;
 #endif
 
+/* Get an environment variable, possibly converted to UTF-8 from wide string.
+   The return value is a copy that you shall free. */
+char *compat_getenv(const char* name);
+
 /**
  * Opening a file handle can be different.
  * This function here is defined to take a path in native encoding (ISO8859 / UTF-8 / ...), or, when MS Windows Unicode support is enabled, an UTF-8 string that will be converted back to native UCS-2 (wide character) before calling the system's open function.
@@ -149,6 +159,10 @@ typedef long ssize_p;
  */
 int compat_open(const char *filename, int flags);
 FILE* compat_fopen(const char *filename, const char *mode);
+/**
+ * Also fdopen to avoid having to define POSIX macros in various source files.
+ */
+FILE* compat_fdopen(int fd, const char *mode);
 
 /**
  * Closing a file handle can be platform specific.
@@ -190,6 +204,67 @@ int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
 int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
 #endif
 
+/*
+       A little bit of path abstraction: We always work with plain char strings
+       that usually represent POSIX-ish UTF-8 paths (something like c:/some/file
+       might appear). For Windows, those are converted to wide strings with \
+       instead of / and possible fun is had with prefixes to get around the old
+       path length limit. Outside of the compat library, that stuff should not
+       matter, although something like //?/UNC/server/some/file could be thrown
+       around as UTF-8 string, to be converted to a wide \\?\UNC\server\some\file
+       just before handing it to Windows API.
+
+       There is a lot of unnecessary memory allocation and string copying because
+       of this, but this filesystem stuff is not really relevant to mpg123
+       performance, so the goal is to keep the code outside the compatibility layer
+       simple.
+*/
+
+/*
+       Concatenate a prefix and a path, one of them alowed to be NULL.
+       If the path is already absolute, the prefix is ignored. Relative
+       parts (like /..) are resolved if this is sensible for the platform
+       (meaning: for Windows), else they are preserved (on POSIX, actual
+       file system access would be needed because of symlinks).
+*/
+char* compat_catpath(const char *prefix, const char* path);
+
+/* Return 1 if the given path indicates an existing directory,
+   0 otherwise. */
+int compat_isdir(const char *path);
+
+/*
+       Directory traversal. This talks ASCII/UTF-8 paths externally, converts
+       to/from wchar_t internally if the platform wants that. Returning NULL
+       means failure to open/end of listing.
+       There is no promise about sorting entries.
+*/
+struct compat_dir;
+/* Returns NULL if either directory failed to open or listing is empty.
+   Listing can still be empty even if non-NULL, so always rely on the
+   nextfile/nextdir functions. */
+struct compat_dir* compat_diropen(char *path);
+void               compat_dirclose(struct compat_dir*);
+/* Get the next entry that is a file (or symlink to one).
+   The returned string is a copy that needs to be freed after use. */
+char* compat_nextfile(struct compat_dir*);
+/* Get the next entry that is a directory (or symlink to one).
+   The returned string is a copy that needs to be freed after use. */
+char* compat_nextdir (struct compat_dir*);
+
+#ifdef USE_MODULES
+/*
+       For keeping the path mess local, a system-specific dlopen() variant
+       is contained in here, too. This is very thin wrapping, even sparing
+       definition of a handle type, just using void pointers.
+       Use of absolute paths is a good idea if you want to be sure which
+       file is openend, as default search paths vary.
+*/
+void *compat_dlopen (const char *path);
+void *compat_dlsym  (void *handle, const char* name);
+void  compat_dlclose(void *handle);
+#endif
+
 /* Blocking write/read of data with signal resilience.
    Both continue after being interrupted by signals and always return the
    amount of processed data (shortage indicating actual problem or EOF). */
index b7853d6..6012ccc 100644 (file)
 #include "config.h"
 #include "intsym.h"
 
+#if (defined OPT_I486)  || (defined OPT_I586) || (defined OPT_I586_DITHER) \
+ || (defined OPT_MMX)   || (defined OPT_SSE)  || (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) \
+ || (defined OPT_3DNOW_VINTAGE) || (defined OPT_3DNOWEXT_VINTAGE) \
+ || (defined OPT_SSE_VINTAGE)
+#define OPT_X86
+#endif
+
 #ifdef CCALIGN
 #define MOVUAPS movaps
 #else
 #define ALIGN32 .align 32
 #define ALIGN64 .align 64
 #else
+#ifdef ASMALIGN_ARMASM
+#define ALIGN4  ALIGN 4
+#define ALIGN8  ALIGN 8
+#define ALIGN16 ALIGN 16
+#define ALIGN32 ALIGN 32
+#define ALIGN64 ALIGN 64
+#else
 #error "Dunno how assembler alignment works. Please specify."
 #endif
 #endif
+#endif
 
 #endif
 
@@ -61,7 +76,7 @@
 #if defined(__USER_LABEL_PREFIX__)
 #define ASM_NAME(a) MANGLE_MACROCAT(__USER_LABEL_PREFIX__,a)
 #define ASM_VALUE(a) MANGLE_MACROCAT($,ASM_NAME(a))
-#elif defined(__CYGWIN__) || defined(_WIN32) && !defined (_WIN64) || defined(__OS2__) || \
+#elif defined(__CYGWIN__) || defined(_WIN32) && !defined (_WIN64) && !defined (_M_ARM) || defined(__OS2__) || \
    (defined(__OpenBSD__) && !defined(__ELF__)) || defined(__APPLE__)
 #define ASM_NAME(a) MANGLE_MACROCAT(_,a)
 #define ASM_VALUE(a) MANGLE_MACROCAT($_,a)
 #define ASM_VALUE(a) MANGLE_MACROCAT($,a)
 #endif
 
+/* Enable position-independent code for certain platforms. */
+
+#if defined(OPT_X86)
+
+#define _EBX_ %ebx
+
+#if defined(PIC) && defined(__ELF__)
+
+/* ELF binaries (Unix/Linux) */
+#define LOCAL_VAR(a) a ## @GOTOFF(_EBX_)
+#define GLOBAL_VAR(a) ASM_NAME(a) ## @GOTOFF(_EBX_)
+#define GLOBAL_VAR_PTR(a) ASM_NAME(a) ## @GOT(_EBX_)
+#define FUNC(a) ASM_NAME(a)
+#define EXTERNAL_FUNC(a) ASM_NAME(a) ## @PLT
+#undef ASM_VALUE
+#define ASM_VALUE(a) MANGLE_MACROCAT($,a) ##@GOTOFF
+#define GET_GOT \
+       call 1f; \
+1: \
+       pop _EBX_; \
+2: \
+       addl $_GLOBAL_OFFSET_TABLE_ + (2b-1b), _EBX_
+#define PREPARE_GOT pushl _EBX_
+#define RESTORE_GOT popl _EBX_
+
+#elif defined(PIC) && defined(__APPLE__)
+
+/* Mach-O binaries (OSX/iOS) */
+#define LOCAL_VAR(a) a ## - Lpic_base(_EBX_)
+#define GLOBAL_VAR(a) #error This ABI cannot access non-local symbols directly.
+#define GLOBAL_VAR_PTR(a) L_ ## a ## - Lpic_base(_EBX_)
+#define FUNC(a) L_ ## a
+#define EXTERNAL_FUNC(a) L_ ## a
+#define GET_GOT \
+       call Lpic_base; \
+Lpic_base: \
+       pop _EBX_
+#define PREPARE_GOT pushl _EBX_
+#define RESTORE_GOT popl _EBX_
+
+#else
+
+/* Dummies for everyone else. */
+#define LOCAL_VAR(a) a
+#define GLOBAL_VAR ASM_NAME
+#define GLOBAL_VAR_PTR(a) #error Cannot use indirect addressing in non-PIC object.
+#define FUNC ASM_NAME
+#define EXTERNAL_FUNC ASM_NAME
+#define GET_GOT
+#define PREPARE_GOT
+#define RESTORE_GOT
+
+#endif /* PIC variants */
+
+#endif /* OPT_X86 */
+
 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)
 #define COMM(a,b,c) .comm a,b
 #else
 #define BSS .bss
 #endif
 
+/* armasm for WIN32 UWP */
+#ifdef _M_ARM
+#define GLOBAL_SYMBOL EXPORT
+#else
+#define GLOBAL_SYMBOL .globl
+#endif
+
 /* Mark non-executable stack.
    It's mainly for GNU on Linux... who else does (not) like this? */
 #if !defined(__SUNPRO_C) && defined(__linux__) && defined(__ELF__)
 #define NONEXEC_STACK
 #endif
 
-#if defined(__x86_64__) && (defined(_WIN64) || defined (__CYGWIN__))
+#if (defined(__x86_64__) || defined(_M_X64)) && (defined(_WIN64) || defined (__CYGWIN__))
 #define IS_MSABI 1 /* Not using SYSV */
 #endif
 
index bf7007f..2e6cbff 100644 (file)
@@ -32,6 +32,7 @@ static inline int16_t idiv_signed_rounded(int32_t x, int shift)
 /* From now on for single precision float... double precision is a possible option once we added some bits. But, it would be rather insane. */
 #ifndef REAL_TO_SHORT
 
+#if (defined FORCE_ACCURATE) || (defined ACCURATE_ROUNDING)
 /* Define the accurate rounding function. */
 # if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
 /* This function is only available for IEEE754 single-precision values
@@ -51,6 +52,7 @@ static inline int16_t ftoi16(float x)
 /* The "proper" rounding, plain C, a bit slow. */
 #  define REAL_TO_SHORT_ACCURATE(x)      (short)((x)>0.0?(x)+0.5:(x)-0.5)
 # endif
+#endif
 
 /* Now define the normal rounding. */
 # ifdef ACCURATE_ROUNDING
index 36c8949..5ebbd94 100644 (file)
        That's not memory efficient since there's doubled code, but it's easier than giving another function pointer.
        Maybe I'll change it in future, but now I need something that works.
 
-       Original comment from MPlayer source follows:
+       Original comment from MPlayer source follows. Regarding the license history see
+       synth_mmx.S, which the original comment about this being licensed under GPL is
+       relating to.
 */
 
 /*
- * this code comes under GPL
  * This code was taken from http://www.mpg123.org
  * See ChangeLog of mpg123-0.59s-pre.1 for detail
  * Applied to mplayer by Nick Kurshev <nickols_k@mail.ru>
@@ -48,11 +49,25 @@ SYNTH_NAME:
        pushl   %ebp
 /* stack:0=ebp 4=back 8=bandptr 12=channel 16=samples 20=buffs 24=bo 28=decwins */
        movl    %esp, %ebp
+
 /* Now the old stack addresses are preserved via %epb. */
+#ifdef PIC
+       subl  $8,%esp /* What has been called temp before. */
+#else
        subl  $4,%esp /* What has been called temp before. */
+#endif
        pushl   %edi
        pushl   %esi
        pushl   %ebx
+
+#ifdef PIC
+       #undef _EBX_
+       #define _EBX_ %eax
+       GET_GOT
+#define EBXSAVE -4(%ebp)
+       movl _EBX_, EBXSAVE /* save PIC register */
+#endif
+
 #define TEMP 12(%esp)
 /* APP */
        movl 12(%ebp),%ecx
@@ -94,6 +109,9 @@ SYNTH_NAME:
        leal (%ecx,%ebx,2), %edx
        movl (%esp),%ecx /* restore, but leave value on stack */
        shrl $1, %ecx
+#ifdef PIC
+       movl EBXSAVE, _EBX_
+#endif
        ALIGN16
 3:
        movq  (%edx),%mm0
@@ -130,8 +148,8 @@ SYNTH_NAME:
        packssdw %mm4,%mm4
        movq    (%edi), %mm1
        punpckldq %mm4, %mm0
-       pand   one_null, %mm1
-       pand   null_one, %mm0
+       pand   LOCAL_VAR(one_null), %mm1
+       pand   LOCAL_VAR(null_one), %mm0
        por    %mm0, %mm1
        movq   %mm1,(%edi)
        leal 64(%esi),%esi
@@ -166,6 +184,10 @@ SYNTH_NAME:
 4:
        subl $64,%esi
        movl $7,%ecx
+
+#ifdef PIC
+       movl EBXSAVE, _EBX_
+#endif
        ALIGN16
 5:
        movq  (%edx),%mm0
@@ -206,8 +228,8 @@ SYNTH_NAME:
        psubsw %mm5,%mm4
        movq    (%edi), %mm1
        punpckldq %mm4, %mm0
-       pand   one_null, %mm1
-       pand   null_one, %mm0
+       pand   LOCAL_VAR(one_null), %mm1
+       pand   LOCAL_VAR(null_one), %mm0
        por    %mm0, %mm1
        movq   %mm1,(%edi)
        subl $64,%esi
@@ -241,6 +263,6 @@ SYNTH_NAME:
        popl    %ebx
        popl    %esi
        popl    %edi
-       addl $4,%esp
+       mov             %ebp, %esp
        popl    %ebp
        ret
index b0163d4..32b24eb 100644 (file)
@@ -15,6 +15,7 @@ include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libmpg
 
 list(APPEND SOURCE
     compat/compat.c
+    compat/compat_str.c
     dct64.c
     dct64_i386.c
     equalizer.c
index f5ea72d..675a2da 100644 (file)
 /*
-       Just to ensure that libraries and programs get their separate
-       compatibility object. There should be a compatibility library,
-       I presume, but I don't want to create another glib, I just want
-       some internal functions to ease coding.
+       compat: Some compatibility functions (basic memory & string stuff in separate file)
 
-       I'll sort it out properly sometime.
+       The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
+       So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
 
-       I smell symbol conflicts, anyway. Actually wondering why it
-       worked so far.
+       copyright 2007-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
+       see COPYING and AUTHORS files in distribution or http://mpg123.org
+       initially written by Thomas Orgis, Windows Unicode stuff by JonY.
 */
 
 #include "config.h"
-#include "intsym.h"
-#define NO_CATCHSIGNAL
-#include "compat/compat_impl.h"
+/* This source file does need _POSIX_SOURCE to get some sigaction. */
+#define _POSIX_SOURCE
+#include "compat.h"
+
+#ifdef _MSC_VER
+#include <io.h>
+
+#if(defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP))
+#define WINDOWS_UWP
+#endif
+
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include <sys/stat.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#  include <dirent.h>
+#endif
+
+/* Win32 is only supported with unicode now. These headers also cover
+   module stuff. The WANT_WIN32_UNICODE macro is synonymous with
+   "want windows-specific API, and only the unicode variants of which". */
+#ifdef WANT_WIN32_UNICODE
+#include <wchar.h>
+#include <windows.h>
+#include <winnls.h>
+#include <shlwapi.h>
+#endif
+
+#ifdef USE_MODULES
+#  ifdef HAVE_DLFCN_H
+#    include <dlfcn.h>
+#  endif
+#endif
+
+#include "debug.h"
+
+#ifndef WINDOWS_UWP
+
+char *compat_getenv(const char* name)
+{
+       char *ret = NULL;
+#ifdef WANT_WIN32_UNICODE
+       wchar_t *env;
+       wchar_t *wname = NULL;
+       if(win32_utf8_wide(name, &wname, NULL) > 0)
+       {
+               env = _wgetenv(wname);
+               free(wname);
+               if(env)
+                       win32_wide_utf8(env, &ret, NULL);
+       }
+#else
+       ret = getenv(name);
+       if(ret)
+               ret = compat_strdup(ret);
+#endif
+       return ret;
+}
+
+#ifdef WANT_WIN32_UNICODE
+
+/* Convert unix UTF-8 (or ASCII) paths to Windows wide character paths. */
+static wchar_t* u2wpath(const char *upath)
+{
+       wchar_t* wpath, *p;
+       if(!upath || win32_utf8_wide(upath, &wpath, NULL) < 1)
+               return NULL;
+       for(p=wpath; *p; ++p)
+               if(*p == L'/')
+                       *p = L'\\';
+       return wpath;
+}
+
+/* Convert Windows wide character paths to unix UTF-8. */
+static char* w2upath(const wchar_t *wpath)
+{
+       char* upath, *p;
+       if(!wpath || win32_wide_utf8(wpath, &upath, NULL) < 1)
+               return NULL;
+       for(p=upath; *p; ++p)
+               if(*p == '\\')
+                       *p = '/';
+       return upath;
+}
+
+/* An absolute path that is too long and not already marked with
+   \\?\ can be marked as a long one and still work. */
+static int wpath_need_elongation(wchar_t *wpath)
+{
+       if( wpath && !PathIsRelativeW(wpath)
+       &&      wcslen(wpath) > MAX_PATH-1
+       &&      wcsncmp(L"\\\\?\\", wpath, 4) )
+               return 1;
+       else
+               return 0;
+}
+
+/* Take any wide windows path and turn it into a path that is allowed
+   to be longer than MAX_PATH, if it is not already. */
+static wchar_t* wlongpath(wchar_t *wpath)
+{
+       size_t len, plen;
+       const wchar_t *prefix = L"";
+       wchar_t *wlpath = NULL;
+       if(!wpath)
+               return NULL;
+
+       /* Absolute paths that do not start with \\?\ get that prepended
+          to allow them being long. */
+       if(!PathIsRelativeW(wpath) && wcsncmp(L"\\\\?\\", wpath, 4))
+       {
+               if(wcslen(wpath) >= 2 && PathIsUNCW(wpath))
+               {
+                       /* \\server\path -> \\?\UNC\server\path */
+                       prefix = L"\\\\?\\UNC";
+                       ++wpath; /* Skip the first \. */
+               }
+               else /* c:\some/path -> \\?\c:\some\path */
+                       prefix = L"\\\\?\\";
+       }
+       plen = wcslen(prefix);
+       len = plen + wcslen(wpath);
+       wlpath = malloc(len+1*sizeof(wchar_t));
+       if(wlpath)
+       {
+               /* Brute force memory copying, swprintf is too dandy. */
+               memcpy(wlpath, prefix, sizeof(wchar_t)*plen);
+               memcpy(wlpath+plen, wpath, sizeof(wchar_t)*(len-plen));
+               wlpath[len] = 0;
+       }
+       return wlpath;
+}
+
+/* Convert unix path to wide windows path, optionally marking
+   it as long path if necessary. */
+static wchar_t* u2wlongpath(const char *upath)
+{
+       wchar_t *wpath  = NULL;
+       wchar_t *wlpath = NULL;
+       wpath = u2wpath(upath);
+       if(wpath_need_elongation(wpath))
+       {
+               wlpath = wlongpath(wpath);
+               free(wpath);
+               wpath = wlpath;
+       }
+       return wpath;
+}
+
+#endif
+
+#else
+
+static wchar_t* u2wlongpath(const char *upath)
+{
+       wchar_t* wpath, *p;
+       if (!upath || win32_utf8_wide(upath, &wpath, NULL) < 1)
+               return NULL;
+       for (p = wpath; *p; ++p)
+               if (*p == L'/')
+                       *p = L'\\';
+       return wpath;
+}
+
+#endif
+
+/* Always add a default permission mask in case of flags|O_CREAT. */
+int compat_open(const char *filename, int flags)
+{
+       int ret;
+#if defined (WANT_WIN32_UNICODE)
+       wchar_t *frag = NULL;
+
+       frag = u2wlongpath(filename);
+       /* Fallback to plain open when ucs-2 conversion fails */
+       if(!frag)
+               goto open_fallback;
+
+       /*Try _wopen */
+       ret = _wopen(frag, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
+       if(ret != -1 )
+               goto open_ok; /* msdn says -1 means failure */
+
+open_fallback:
+#endif
+
+#if (defined(WIN32) && !defined (__CYGWIN__))
+       /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
+       /* Try plain old _open(), if it fails, do nothing */
+       ret = _open(filename, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
+#else
+       ret = open(filename, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+#endif
+
+#if defined (WANT_WIN32_UNICODE)
+open_ok:
+       free(frag);
+#endif
+
+       return ret;
+}
+
+/* Moved over from wav.c, logic with fallbacks added from the
+   example of compat_open(). */
+FILE* compat_fopen(const char *filename, const char *mode)
+{
+       FILE* stream = NULL;
+#ifdef WANT_WIN32_UNICODE
+       int cnt = 0;
+       wchar_t *wname = NULL;
+       wchar_t *wmode = NULL;
+
+       wname = u2wlongpath(filename);
+       if(!wname)
+               goto fopen_fallback;
+       cnt = win32_utf8_wide(mode, &wmode, NULL);
+       if( (wmode == NULL) || (cnt == 0))
+               goto fopen_fallback;
+
+       stream = _wfopen(wname, wmode);
+       if(stream) goto fopen_ok;
+
+fopen_fallback:
+#endif
+       stream = fopen(filename, mode);
+#ifdef WANT_WIN32_UNICODE
+
+fopen_ok:
+       free(wmode);
+       free(wname);
+#endif
+       return stream;
+}
+
+FILE* compat_fdopen(int fd, const char *mode)
+{
+       return fdopen(fd, mode);
+}
+
+int compat_close(int infd)
+{
+#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
+       return _close(infd);
+#else
+       return close(infd);
+#endif
+}
+
+int compat_fclose(FILE *stream)
+{
+       return fclose(stream);
+}
+
+/* Windows Unicode stuff */
+
+#ifdef WANT_WIN32_UNICODE
+int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
+{
+  size_t len;
+  char *buf;
+  int ret = 0;
+
+  len = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
+  buf = calloc(len + 1, sizeof (char)); /* Can we assume sizeof char always = 1? */
+
+  if(!buf) len = 0;
+  else {
+    if (len != 0) ret = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
+    buf[len] = '0'; /* Must terminate */
+  }
+  *mbptr = buf; /* Set string pointer to allocated buffer */
+  if(buflen != NULL) *buflen = (len) * sizeof (char); /* Give length of allocated memory if needed. */
+  return ret;
+}
+
+int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
+{
+  size_t len;
+  wchar_t *buf;
+  int ret = 0;
+
+  len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, NULL, 0); /* Get converted size */
+  buf = calloc(len + 1, sizeof (wchar_t)); /* Allocate memory accordingly */
+
+  if(!buf) len = 0;
+  else {
+    if (len != 0) ret = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, buf, len); /* Do conversion */
+    buf[len] = L'0'; /* Must terminate */
+  }
+  *wptr = buf; /* Set string pointer to allocated buffer */
+  if (buflen != NULL) *buflen = len * sizeof (wchar_t); /* Give length of allocated memory if needed. */
+  return ret; /* Number of characters written */
+}
+#endif
+
+#ifndef WINDOWS_UWP
+
+/*
+       The Windows file and path stuff is an extract of jon_y's win32 loader
+       prototype from the loader_rework branch. It's been divided in to
+       reusable functons by ThOr in the hope to work out some generic-looking
+       loader code for both POSIX and Windows. The routines might be
+       helpful for consistent path work in other parts of mpg123, too.
+
+       This all is about getting some working code on a wide range of
+       systems while staying somewhat sane. If it does ridiculously inefficient
+       things with extraneous copies and grabbing of functions that made
+       it late to some official APIs, that's still fine with us.
+*/
+
+char* compat_catpath(const char *prefix, const char* path)
+{
+       char *ret = NULL;
+#ifdef WANT_WIN32_UNICODE
+       wchar_t *wprefix = NULL; /* Wide windows versions of */
+       wchar_t *wpath   = NULL; /* input arguments. */
+       wchar_t *locwret = NULL; /* Tmp return value from LocalAlloc */
+       /*
+               This variation of combinepath can work with long and UNC paths, but
+               is not officially exposed in any DLLs, It also allocates all its buffers
+               internally via LocalAlloc, avoiding buffer overflow problems.
+               ThOr: I presume this hack is for supporting pre-8 Windows, as
+               from Windows 8 on, this is documented in the API.
+       */
+       HRESULT (__stdcall *mypac)( const wchar_t *in, const wchar_t* more
+       ,       unsigned long flags, wchar_t **out ) = NULL;
+       HMODULE pathcch = NULL;
+
+       if(!prefix && !path)
+               goto catpath_end;
+       wprefix = u2wpath(prefix);
+       wpath   = u2wpath(path);
+       if((prefix && !wprefix) || (path && !wpath))
+               goto catpath_end;
+
+       /* Again: I presume this whole fun is to get at PathAllocCombine
+          even when pathcch.h is not available (like in MinGW32). */
+       if( (pathcch = GetModuleHandleA("kernelbase")) )
+               mypac = (void *)GetProcAddress(pathcch, "PathAllocCombine");
+       if(mypac) /* PATHCCH_ALLOW_LONG_PATH = 1 per API docs */
+       {
+               debug("Actually calling PathAllocCombine!");
+               mypac(wprefix, wpath, 1, &locwret);
+       }
+       else
+       {
+               /* Playing safe, if we'd care much about performance, this would be on
+                  the stack. */
+               locwret = LocalAlloc(LPTR, sizeof(wchar_t)*MAX_PATH);
+               if(locwret)
+                       PathCombineW(locwret, wprefix, wpath);
+       }
+       ret = w2upath(locwret);
+
+catpath_end:
+       LocalFree(locwret);
+       free(wprefix);
+       free(wpath);
+#else
+       size_t len, prelen, patlen;
+
+       if(path && path[0] == '/')
+               prefix = NULL; /* Absolute path stays as it is. */
+       prelen = prefix ? strlen(prefix) : 0;
+       patlen = path   ? strlen(path)   : 0;
+       /* Concatenate the two, put a / in between if both present. */
+       len = ((prefix && path) ? 1 : 0) + prelen + patlen;
+       ret = malloc(len+1);
+       if(ret)
+       {
+               size_t off=0;
+               memcpy(ret, prefix, prelen);
+               if(prefix && path)
+                       ret[prelen+(off++)] = '/';
+               memcpy(ret+prelen+off, path, patlen);
+               ret[len] = 0;
+       }
+#endif
+       return ret;
+}
+
+int compat_isdir(const char *path)
+{
+       int ret = 0;
+#ifdef WANT_WIN32_UNICODE
+       wchar_t *wpath;
+       wpath = u2wlongpath(path);
+       if(wpath)
+       {
+               DWORD attr = GetFileAttributesW(wpath);
+               if(attr != INVALID_FILE_ATTRIBUTES && attr & FILE_ATTRIBUTE_DIRECTORY)
+                       ret=1;
+               free(wpath);
+       }
+#else
+       struct stat sb;
+       if(path && !stat(path, &sb))
+       {
+               if(S_ISDIR(sb.st_mode))
+                       ret=1;
+       }
+#endif
+       return ret;
+}
+
+struct compat_dir
+{
+       char *path;
+#ifdef WANT_WIN32_UNICODE
+       int gotone; /* Got a result stored from FindFirstFileW. */
+       WIN32_FIND_DATAW d;
+       HANDLE ffn;
+#else
+       DIR* dir;
+#endif
+};
+
+struct compat_dir* compat_diropen(char *path)
+{
+       struct compat_dir *cd;
+       if(!path)
+               return NULL;
+       cd = malloc(sizeof(*cd));
+       if(!cd)
+               return NULL;
+#ifdef WANT_WIN32_UNICODE
+       cd->gotone = 0;
+       {
+               char *pattern;
+               wchar_t *wpattern;
+               pattern = compat_catpath(path, "*");
+               wpattern = u2wlongpath(pattern);
+               if(wpattern)
+               {
+                       cd->ffn = FindFirstFileW(wpattern, &(cd->d));
+                       if(cd->ffn == INVALID_HANDLE_VALUE)
+                       {
+                               /* FindClose() only needed after successful first find, right? */
+                               free(cd);
+                               cd = NULL;
+                       }
+                       else
+                               cd->gotone = 1;
+               }
+               free(wpattern);
+               free(pattern);
+       }
+#else
+       cd->dir = opendir(path);
+       if(!cd->dir)
+       {
+               free(cd);
+               cd = NULL;
+       }
+#endif
+       if(cd)
+       {
+               cd->path = compat_strdup(path);
+               if(!cd->path)
+               {
+                       compat_dirclose(cd);
+                       cd = NULL;
+               }
+       }
+       return cd;
+}
+
+void compat_dirclose(struct compat_dir *cd)
+{
+       if(cd)
+       {
+               free(cd->path);
+#ifdef WANT_WIN32_UNICODE
+               FindClose(cd->ffn);
+#else
+               closedir(cd->dir);
+#endif
+               free(cd);
+       }
+}
+
+char* compat_nextfile(struct compat_dir *cd)
+{
+       if(!cd)
+               return NULL;
+#ifdef WANT_WIN32_UNICODE
+       while(cd->gotone || FindNextFileW(cd->ffn, &(cd->d)))
+       {
+               cd->gotone = 0;
+               if(!(cd->d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+               {
+                       char *ret;
+                       win32_wide_utf8(cd->d.cFileName, &ret, NULL);
+                       return ret;
+               }
+       }
+#else
+       {
+               struct dirent *dp;
+               while((dp = readdir(cd->dir)))
+               {
+                       struct stat fst;
+                       char *fullpath = compat_catpath(cd->path, dp->d_name);
+                       if(fullpath && !stat(fullpath, &fst) && S_ISREG(fst.st_mode))
+                       {
+                               free(fullpath);
+                               return compat_strdup(dp->d_name);
+                       }
+                       free(fullpath);
+               }
+       }
+#endif
+       return NULL;
+}
+
+char* compat_nextdir(struct compat_dir *cd)
+{
+       if(!cd)
+               return NULL;
+#ifdef WANT_WIN32_UNICODE
+       while(cd->gotone || FindNextFileW(cd->ffn, &(cd->d)))
+       {
+               cd->gotone = 0;
+               if(cd->d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+               {
+                       char *ret;
+                       win32_wide_utf8(cd->d.cFileName, &ret, NULL);
+                       return ret;
+               }
+       }
+#else
+       {
+               struct dirent *dp;
+               while((dp = readdir(cd->dir)))
+               {
+                       struct stat fst;
+                       char *fullpath = compat_catpath(cd->path, dp->d_name);
+                       if(fullpath && !stat(fullpath, &fst) && S_ISDIR(fst.st_mode))
+                       {
+                               free(fullpath);
+                               return compat_strdup(dp->d_name);
+                       }
+                       free(fullpath);
+               }
+       }
+#endif
+       return NULL;
+}
+
+#endif
+
+#ifdef USE_MODULES
+/*
+       This is what I expected the platform-specific dance for dynamic module
+       support to be. Little did I know about the peculiarities of (long)
+       paths and directory/file search on Windows.
+*/
+
+void *compat_dlopen(const char *path)
+{
+       void *handle = NULL;
+#ifdef WANT_WIN32_UNICODE
+       wchar_t *wpath;
+       wpath = u2wlongpath(path);
+       if(wpath)
+               handle = LoadLibraryW(wpath);
+       free(wpath);
+#else
+       handle = dlopen(path, RTLD_NOW);
+#endif
+       return handle;
+}
+
+void *compat_dlsym(void *handle, const char *name)
+{
+       void *sym = NULL;
+       if(!handle)
+               return NULL;
+#ifdef WANT_WIN32_UNICODE
+       sym = GetProcAddress(handle, name);
+#else
+       sym = dlsym(handle, name);
+#endif
+       return sym;
+}
+
+void compat_dlclose(void *handle)
+{
+       if(!handle)
+               return;
+#ifdef WANT_WIN32_UNICODE
+       FreeLibrary(handle);
+#else
+       dlclose(handle);
+#endif
+}
+
+#endif /* USE_MODULES */
+
+
+/* This shall survive signals and any return value less than given byte count
+   is an error */
+size_t unintr_write(int fd, void const *buffer, size_t bytes)
+{
+       size_t written = 0;
+       while(bytes)
+       {
+               ssize_t part = write(fd, (char*)buffer+written, bytes);
+               if(part < 0 && errno != EINTR)
+                       break;
+               bytes   -= part;
+               written += part;
+       }
+       return written;
+}
+
+/* Same for reading the data. */
+size_t unintr_read(int fd, void *buffer, size_t bytes)
+{
+       size_t got = 0;
+       while(bytes)
+       {
+               ssize_t part = read(fd, (char*)buffer+got, bytes);
+               if(part < 0 && errno != EINTR)
+                       break;
+               bytes -= part;
+               got   += part;
+       }
+       return got;
+}
+
+#ifndef NO_CATCHSIGNAL
+#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
+void (*catchsignal(int signum, void(*handler)()))()
+{
+       struct sigaction new_sa;
+       struct sigaction old_sa;
+
+#ifdef DONT_CATCH_SIGNALS
+       fprintf (stderr, "Not catching any signals.\n");
+       return ((void (*)()) -1);
+#endif
+
+       new_sa.sa_handler = handler;
+       sigemptyset(&new_sa.sa_mask);
+       new_sa.sa_flags = 0;
+       if(sigaction(signum, &new_sa, &old_sa) == -1)
+               return ((void (*)()) -1);
+       return (old_sa.sa_handler);
+}
+#endif
+#endif
diff --git a/reactos/sdk/lib/3rdparty/libmpg123/compat/compat_impl.h b/reactos/sdk/lib/3rdparty/libmpg123/compat/compat_impl.h
deleted file mode 100644 (file)
index 553cfde..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-       compat: Some compatibility functions.
-
-       The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
-       So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
-
-       copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
-       see COPYING and AUTHORS files in distribution or http://mpg123.org
-       initially written by Thomas Orgis, Windows Unicode stuff by JonY.
-*/
-
-#include "config.h"
-#include "compat.h"
-
-#ifdef _MSC_VER
-#include <io.h>
-#else
-#include <fcntl.h>
-#endif
-#include <sys/stat.h>
-
-#ifdef WANT_WIN32_UNICODE
-#include <wchar.h>
-#include <windows.h>
-#include <winnls.h>
-#endif
-
-#include "debug.h"
-
-/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
-void *safe_realloc(void *ptr, size_t size)
-{
-       if(ptr == NULL) return malloc(size);
-       else return realloc(ptr, size);
-}
-
-#ifndef HAVE_STRERROR
-const char *strerror(int errnum)
-{
-       extern int sys_nerr;
-       extern char *sys_errlist[];
-
-       return (errnum < sys_nerr) ?  sys_errlist[errnum]  :  "";
-}
-#endif
-
-#ifndef HAVE_STRDUP
-char *strdup(const char *src)
-{
-       char *dest;
-
-       if (!(dest = (char *) malloc(strlen(src)+1)))
-       return NULL;
-       else
-       return strcpy(dest, src);
-}
-#endif
-
-/* Always add a default permission mask in case of flags|O_CREAT. */
-int compat_open(const char *filename, int flags)
-{
-       int ret;
-#if defined (WANT_WIN32_UNICODE)
-       wchar_t *frag = NULL;
-
-       ret = win32_utf8_wide(filename, &frag, NULL);
-       /* Fallback to plain open when ucs-2 conversion fails */
-       if((frag == NULL) || (ret == 0))
-               goto open_fallback;
-
-       /*Try _wopen */
-       ret = _wopen(frag, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
-       if(ret != -1 )
-               goto open_ok; /* msdn says -1 means failure */
-
-open_fallback:
-#endif
-
-#if (defined(WIN32) && !defined (__CYGWIN__))
-       /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
-       /* Try plain old _open(), if it fails, do nothing */
-       ret = _open(filename, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
-#else
-       ret = open(filename, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
-#endif
-
-#if defined (WANT_WIN32_UNICODE)
-open_ok:
-       /* A cast to void*? Does Windows need that?! */
-       free((void *)frag);
-#endif
-
-       return ret;
-}
-
-/* Moved over from wav.c, logic with fallbacks added from the
-   example of compat_open(). */
-FILE* compat_fopen(const char *filename, const char *mode)
-{
-       FILE* stream = NULL;
-#ifdef WANT_WIN32_UNICODE
-       int cnt = 0;
-       wchar_t *wname = NULL;
-       wchar_t *wmode = NULL;
-
-       cnt = win32_utf8_wide(filename, &wname, NULL);
-       if( (wname == NULL) || (cnt == 0))
-               goto fopen_fallback;
-       cnt = win32_utf8_wide(mode, &wmode, NULL);
-       if( (wmode == NULL) || (cnt == 0))
-               goto fopen_fallback;
-
-       stream = _wfopen(wname, wmode);
-       if(stream) goto fopen_ok;
-
-fopen_fallback:
-#endif
-       stream = fopen(filename, mode);
-#ifdef WANT_WIN32_UNICODE
-
-fopen_ok:
-       free(wmode);
-       free(wname);
-#endif
-       return stream;
-}
-
-int compat_close(int infd)
-{
-#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
-       return _close(infd);
-#else
-       return close(infd);
-#endif
-}
-
-int compat_fclose(FILE *stream)
-{
-       return fclose(stream);
-}
-
-/* Windows Unicode stuff */
-
-#ifdef WANT_WIN32_UNICODE
-int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
-{
-  size_t len;
-  char *buf;
-  int ret = 0;
-
-  len = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
-  buf = calloc(len + 1, sizeof (char)); /* Can we assume sizeof char always = 1? */
-
-  if(!buf) len = 0;
-  else {
-    if (len != 0) ret = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
-    buf[len] = '0'; /* Must terminate */
-  }
-  *mbptr = buf; /* Set string pointer to allocated buffer */
-  if(buflen != NULL) *buflen = (len) * sizeof (char); /* Give length of allocated memory if needed. */
-  return ret;
-}
-
-int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
-{
-  size_t len;
-  wchar_t *buf;
-  int ret = 0;
-
-  len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, NULL, 0); /* Get converted size */
-  buf = calloc(len + 1, sizeof (wchar_t)); /* Allocate memory accordingly */
-
-  if(!buf) len = 0;
-  else {
-    if (len != 0) ret = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, buf, len); /* Do conversion */
-    buf[len] = L'0'; /* Must terminate */
-  }
-  *wptr = buf; /* Set string pointer to allocated buffer */
-  if (buflen != NULL) *buflen = len * sizeof (wchar_t); /* Give length of allocated memory if needed. */
-  return ret; /* Number of characters written */
-}
-#endif
-
-
-/* This shall survive signals and any return value less than given byte count
-   is an error */
-size_t unintr_write(int fd, void const *buffer, size_t bytes)
-{
-       size_t written = 0;
-       while(bytes)
-       {
-               ssize_t part = write(fd, (char*)buffer+written, bytes);
-               if(part < 0 && errno != EINTR)
-                       break;
-               bytes   -= part;
-               written += part;
-       }
-       return written;
-}
-
-/* Same for reading the data. */
-size_t unintr_read(int fd, void *buffer, size_t bytes)
-{
-       size_t got = 0;
-       while(bytes)
-       {
-               ssize_t part = read(fd, (char*)buffer+got, bytes);
-               if(part < 0 && errno != EINTR)
-                       break;
-               bytes -= part;
-               got   += part;
-       }
-       return got;
-}
-
-#ifndef NO_CATCHSIGNAL
-#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
-void (*catchsignal(int signum, void(*handler)()))()
-{
-       struct sigaction new_sa;
-       struct sigaction old_sa;
-
-#ifdef DONT_CATCH_SIGNALS
-       fprintf (stderr, "Not catching any signals.\n");
-       return ((void (*)()) -1);
-#endif
-
-       new_sa.sa_handler = handler;
-       sigemptyset(&new_sa.sa_mask);
-       new_sa.sa_flags = 0;
-       if(sigaction(signum, &new_sa, &old_sa) == -1)
-               return ((void (*)()) -1);
-       return (old_sa.sa_handler);
-}
-#endif
-#endif
diff --git a/reactos/sdk/lib/3rdparty/libmpg123/compat/compat_str.c b/reactos/sdk/lib/3rdparty/libmpg123/compat/compat_str.c
new file mode 100644 (file)
index 0000000..f58fc23
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+       compat: Some compatibility functions (basic memory and string stuff)
+
+       The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
+       So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
+
+       copyright 2007-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
+       see COPYING and AUTHORS files in distribution or http://mpg123.org
+       initially written by Thomas Orgis, Windows Unicode stuff by JonY.
+*/
+
+#include "compat.h"
+#include "debug.h"
+
+/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
+void *safe_realloc(void *ptr, size_t size)
+{
+       if(ptr == NULL) return malloc(size);
+       else return realloc(ptr, size);
+}
+
+#ifndef HAVE_STRERROR
+const char *strerror(int errnum)
+{
+       extern int sys_nerr;
+       extern char *sys_errlist[];
+
+       return (errnum < sys_nerr) ?  sys_errlist[errnum]  :  "";
+}
+#endif
+
+char* compat_strdup(const char *src)
+{
+       char *dest = NULL;
+       if(src)
+       {
+               size_t len;
+               len = strlen(src)+1;
+               if((dest = malloc(len)))
+                       memcpy(dest, src, len);
+       }
+       return dest;
+}
index 3b989f8..71605d2 100644 (file)
@@ -384,7 +384,7 @@ icy2utf8(const char *src, int force)
 
        /* Some funny streams from Apple/iTunes give ICY info in UTF-8 already.
           So, be prepared and don't try to re-encode such. Unless forced. */
-       if(!force && is_utf8(src)) return (strdup(src));
+       if(!force && is_utf8(src)) return (compat_strdup(src));
 
        srclen = strlen(src) + 1;
        /* allocate conservatively */
index 90c8332..3b9740d 100644 (file)
@@ -656,6 +656,9 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
        unsigned char flags = 0;
        int ret = 1;
        int ret2;
+#ifndef NO_ID3V2
+       int skiptag = 0;
+#endif
        unsigned char major = first4bytes & 0xff;
        debug1("ID3v2: major tag version: %i", major);
        if(major == 0xff) return 0; /* Invalid... */
@@ -706,17 +709,28 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
 #ifndef NO_ID3V2
        if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
        /* skip if unknown version/scary flags, parse otherwise */
-       if(fr->p.flags & MPG123_SKIP_ID3V2 || ((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2)))
+       if(fr->p.flags & MPG123_SKIP_ID3V2)
+       {
+               if(VERBOSE3)
+                       fprintf(stderr, "Note: Skipping ID3v2 tag per user request.\n");
+               skiptag = 1;
+       }
+       if((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2))
        {
                if(NOQUIET)
-               {
-                       if(fr->p.flags & MPG123_SKIP_ID3V2)
-                       {
-                               if(VERBOSE3) fprintf(stderr, "Note: Skipping ID3v2 tag per user request.\n");
-                       }
-                       else /* Must be because of scary Tag properties. */
-                       warning2("ID3v2: Won't parse the ID3v2 tag with major version %u and flags 0x%xu - some extra code may be needed", major, flags);
-               }
+                       warning2( "ID3v2: Won't parse the ID3v2 tag with major version"
+                               " %u and flags 0x%xu - some extra code may be needed"
+                       ,       major, flags );
+               skiptag = 1;
+       }
+       if(length < 10)
+       {
+               if(NOQUIET)
+                       warning1("ID3v2: unrealistic small tag lengh %lu, skipping", length);
+               skiptag = 1;
+       }
+       if(skiptag)
+       {
 #endif
                if((ret2 = fr->rd->skip_bytes(fr,length)) < 0) /* will not store data in backbuff! */
                ret = ret2;
index 4f8329e..cc77905 100644 (file)
@@ -11,6 +11,9 @@
 #include "debug.h"
 
 #include "gapless.h"
+/* Want accurate rounding function regardless of decoder setup. */
+#define FORCE_ACCURATE
+#include "sample.h"
 
 #define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
 
@@ -31,6 +34,15 @@ int attribute_align_arg mpg123_init(void)
        prepare_decode_tables();
        check_decoders();
        initialized = 1;
+#if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
+       /* This is rather pointless but it eases my mind to check that we did
+          not enable the special rounding on a VAX or something. */
+       if(12346 != REAL_TO_SHORT_ACCURATE(12345.67f))
+       {
+               error("Bad IEEE 754 rounding. Re-build libmpg123 properly.");
+               return MPG123_ERR;
+       }
+#endif
        return MPG123_OK;
 }
 
@@ -357,7 +369,7 @@ int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key
                {
                        size_t sval = bc_fill(&mh->rdat.buffer);
                        theval = (long)sval;
-                       if((size_t)theval != sval)
+                       if(theval < 0 || (size_t)theval != sval)
                        {
                                mh->err = MPG123_INT_OVERFLOW;
                                ret = MPG123_ERR;
@@ -1035,7 +1047,8 @@ int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *
        return MPG123_OK;
 }
 
-int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
+int attribute_align_arg mpg123_getformat2( mpg123_handle *mh
+,      long *rate, int *channels, int *encoding, int clear_flag )
 {
        int b;
 
@@ -1046,10 +1059,15 @@ int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *cha
        if(rate != NULL) *rate = mh->af.rate;
        if(channels != NULL) *channels = mh->af.channels;
        if(encoding != NULL) *encoding = mh->af.encoding;
-       mh->new_format = 0;
+       if(clear_flag) mh->new_format = 0;
        return MPG123_OK;
 }
 
+int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
+{
+       return mpg123_getformat2(mh, rate, channels, encoding, 1);
+}
+
 off_t attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double seconds)
 {
        off_t b;
index 88c0fed..58dad6d 100644 (file)
@@ -1049,8 +1049,10 @@ static int default_init(mpg123_handle *fr)
        if(fr->p.icy_interval > 0) fr->rdat.lseek = nix_lseek;
 #endif
 
-       fr->rdat.filelen = get_fileinfo(fr);
+       fr->rdat.filelen = fr->p.flags & MPG123_NO_PEEK_END ? -1 : get_fileinfo(fr);
        fr->rdat.filepos = 0;
+       if(fr->p.flags & MPG123_FORCE_SEEKABLE)
+               fr->rdat.flags |= READER_SEEKABLE;
        /*
                Don't enable seeking on ICY streams, just plain normal files.
                This check is necessary since the client can enforce ICY parsing on files that would otherwise be seekable.
index 7e7e245..ed927d9 100644 (file)
@@ -7,6 +7,9 @@
 */
 
 #include "mpg123lib_intern.h"
+#ifdef OPT_GENERIC_DITHER
+#define FORCE_ACCURATE
+#endif
 #include "sample.h"
 #include "debug.h"