diff --git a/reactos/dll/win32/winemp3.acm/CMakeLists.txt b/reactos/dll/win32/winemp3.acm/CMakeLists.txt index 241be693a62..3ad86b6c51f 100644 --- a/reactos/dll/win32/winemp3.acm/CMakeLists.txt +++ b/reactos/dll/win32/winemp3.acm/CMakeLists.txt @@ -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) diff --git a/reactos/sdk/include/reactos/libs/libmpg123/compat.h b/reactos/sdk/include/reactos/libs/libmpg123/compat.h index 3cbc60d50a1..74e0bdd7682 100644 --- a/reactos/sdk/include/reactos/libs/libmpg123/compat.h +++ b/reactos/sdk/include/reactos/libs/libmpg123/compat.h @@ -15,10 +15,14 @@ #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 @@ -98,8 +102,10 @@ 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 +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). */ diff --git a/reactos/sdk/include/reactos/libs/libmpg123/mangle.h b/reactos/sdk/include/reactos/libs/libmpg123/mangle.h index b7853d619cd..6012ccc3d73 100644 --- a/reactos/sdk/include/reactos/libs/libmpg123/mangle.h +++ b/reactos/sdk/include/reactos/libs/libmpg123/mangle.h @@ -13,6 +13,13 @@ #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 @@ -49,9 +56,17 @@ #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) @@ -70,6 +85,62 @@ #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 @@ -82,6 +153,13 @@ #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__) @@ -94,7 +172,7 @@ #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 diff --git a/reactos/sdk/include/reactos/libs/libmpg123/sample.h b/reactos/sdk/include/reactos/libs/libmpg123/sample.h index bf7007f4848..2e6cbff636c 100644 --- a/reactos/sdk/include/reactos/libs/libmpg123/sample.h +++ b/reactos/sdk/include/reactos/libs/libmpg123/sample.h @@ -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 diff --git a/reactos/sdk/include/reactos/libs/libmpg123/synth_sse3d.h b/reactos/sdk/include/reactos/libs/libmpg123/synth_sse3d.h index 36c894903fb..5ebbd940a6c 100644 --- a/reactos/sdk/include/reactos/libs/libmpg123/synth_sse3d.h +++ b/reactos/sdk/include/reactos/libs/libmpg123/synth_sse3d.h @@ -15,11 +15,12 @@ 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 @@ -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 diff --git a/reactos/sdk/lib/3rdparty/libmpg123/CMakeLists.txt b/reactos/sdk/lib/3rdparty/libmpg123/CMakeLists.txt index b0163d48f7c..32b24ebebf7 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/CMakeLists.txt +++ b/reactos/sdk/lib/3rdparty/libmpg123/CMakeLists.txt @@ -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 diff --git a/reactos/sdk/lib/3rdparty/libmpg123/compat/compat.c b/reactos/sdk/lib/3rdparty/libmpg123/compat/compat.c index f5ea72d4004..675a2dab7f5 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/compat/compat.c +++ b/reactos/sdk/lib/3rdparty/libmpg123/compat/compat.c @@ -1,16 +1,665 @@ /* - 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 + +#if(defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP)) +#define WINDOWS_UWP +#endif + +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_DIRENT_H +# include +#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 +#include +#include +#include +#endif + +#ifdef USE_MODULES +# ifdef HAVE_DLFCN_H +# include +# 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 index 553cfde7168..00000000000 --- a/reactos/sdk/lib/3rdparty/libmpg123/compat/compat_impl.h +++ /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 -#else -#include -#endif -#include - -#ifdef WANT_WIN32_UNICODE -#include -#include -#include -#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 index 00000000000..f58fc2382dd --- /dev/null +++ b/reactos/sdk/lib/3rdparty/libmpg123/compat/compat_str.c @@ -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; +} diff --git a/reactos/sdk/lib/3rdparty/libmpg123/icy2utf8.c b/reactos/sdk/lib/3rdparty/libmpg123/icy2utf8.c index 3b989f8312c..71605d2ac67 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/icy2utf8.c +++ b/reactos/sdk/lib/3rdparty/libmpg123/icy2utf8.c @@ -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 */ diff --git a/reactos/sdk/lib/3rdparty/libmpg123/id3.c b/reactos/sdk/lib/3rdparty/libmpg123/id3.c index 90c833299cc..3b9740d9fb1 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/id3.c +++ b/reactos/sdk/lib/3rdparty/libmpg123/id3.c @@ -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; diff --git a/reactos/sdk/lib/3rdparty/libmpg123/libmpg123.c b/reactos/sdk/lib/3rdparty/libmpg123/libmpg123.c index 4f8329e7116..cc77905e58f 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/libmpg123.c +++ b/reactos/sdk/lib/3rdparty/libmpg123/libmpg123.c @@ -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; diff --git a/reactos/sdk/lib/3rdparty/libmpg123/readers.c b/reactos/sdk/lib/3rdparty/libmpg123/readers.c index 88c0fed26a5..58dad6d204d 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/readers.c +++ b/reactos/sdk/lib/3rdparty/libmpg123/readers.c @@ -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. diff --git a/reactos/sdk/lib/3rdparty/libmpg123/synth.c b/reactos/sdk/lib/3rdparty/libmpg123/synth.c index 7e7e24508ed..ed927d9344d 100644 --- a/reactos/sdk/lib/3rdparty/libmpg123/synth.c +++ b/reactos/sdk/lib/3rdparty/libmpg123/synth.c @@ -7,6 +7,9 @@ */ #include "mpg123lib_intern.h" +#ifdef OPT_GENERIC_DITHER +#define FORCE_ACCURATE +#endif #include "sample.h" #include "debug.h"